Como mencionado em Por que um pacote de software roda muito bem mesmo quando está sendo atualizado? , o bloqueio é colocado no inode e não no nome do arquivo. Quando você carrega e executa um binário, o arquivo é marcado como ocupado - e é por isso que você obtém o erro ETXTBSY (arquivo ocupado) quando tenta gravar nele.
Agora, para bibliotecas compartilhadas, é um pouco diferente: as bibliotecas obtêm a memória mapeada no espaço de endereço do processo com mmap()
. Embora MAP_DENYWRITE
possa ser especificado, pelo menos a Glibc no Linux a ignora silenciosamente (de acordo com a página man, sinta-se à vontade para verificar as fontes) - marque esta thread . Portanto, você tem permissão para gravar o arquivo e, como é mapeado na memória, todas as alterações são visíveis quase que imediatamente - o que significa que, se você se esforçar o suficiente, poderá conseguir brick sua máquina sobrescrevendo a biblioteca.
A maneira correta de atualizar, portanto, é:
-
removendo o arquivo, o que remove a referência aos dados do sistema de arquivos, para que ele não seja acessível para aplicativos recém-gerados que possam usá-lo, mantendo os dados acessíveis para qualquer pessoa que já tenha é aberto (ou mapeado);
-
criando um novo arquivo com conteúdo atualizado.
Processos recém-criados usarão o conteúdo atualizado, os aplicativos em execução acessarão a versão antiga. Isso é o que qualquer utilitário de gerenciamento de pacote sensato faz. Note que não é completamente sem nenhum perigo - por exemplo, aplicativos dinamicamente carregando código (usando dlsym()
e amigos) terão problemas se a API da biblioteca mudar silenciosamente.
Se você quiser estar realmente seguro, seguro, desligue o sistema, monte o sistema de arquivos a partir de outra instância do sistema operacional, atualize e atualize o sistema atualizado novamente.