Aqui diz que você pode reescrever um arquivo executável e o processo será executado corretamente - será relido quando um processo reiniciar.
No entanto, quando tento substituir um arquivo binário enquanto o processo está em execução (com scp, do dev para o servidor de teste), ele diz 'arquivo ocupado'. E se eu substituir um arquivo de biblioteca compartilhada (* .so), todos os processos que o vinculam falham.
Por quê então? Estou esquecendo de algo? Como posso substituir os arquivos binários sem parar / travar um processo?
.so
arquivo usandoldd filename.so
a dependências de verificaçãostop app && create symlink of .so && start app
Respostas:
Conforme mencionado em Por que um pacote de software funciona 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ê recebe o erro ETXTBSY (arquivo ocupado) ao tentar gravar nele.
Agora, para bibliotecas compartilhadas, é um pouco diferente: as bibliotecas são mapeadas na memória no espaço de endereço do processo
mmap()
. EmboraMAP_DENYWRITE
possa ser especificado, pelo menos o Glibc no Linux o ignora silenciosamente (de acordo com a página do manual, fique à vontade para verificar as fontes) - verifique este tópico . Portanto, você tem permissão para gravar o arquivo e, como ele é mapeado na memória, quaisquer alterações são visíveis quase imediatamente - o que significa que, se você se esforçar o suficiente, poderá gerenciar a sua máquina em blocos substituindo a biblioteca.A maneira correta de atualizar, portanto, é:
remover o arquivo, que remove a referência aos dados do sistema de arquivos, para que não fique acessível para aplicativos recém-gerados que possam querer usá-lo, mantendo os dados acessíveis para quem já os tem aberto (ou mapeado) ;
criando um novo arquivo com conteúdo atualizado.
Os processos criados recentemente usarão o conteúdo atualizado, os aplicativos em execução acessarão a versão antiga. É isso que qualquer utilitário de gerenciamento de pacotes sã faz. Observe que não é completamente sem perigo - por exemplo, aplicativos que carregam código dinamicamente (usando
dlsym()
e amigos) terão problemas se a API da biblioteca mudar silenciosamente.Se você deseja estar do lado realmente seguro, desligue o sistema, monte o sistema de arquivos a partir de outra instância do sistema operacional, atualize e abra o sistema atualizado novamente.
fonte
Uma atualização de rpm faz o mesmo - com binários e bibliotecas em execução, enquanto nada falha.
Então qual é a diferença:
Isso NÃO substituirá o arquivo no local: O inode referente ao binário em uso ainda está "ocupado" até que o último objeto que o mantém aberto seja concluído. O novo arquivo será criado com um novo número de inode.
Agora
scp
oucp
tentará substituir o arquivo no local - o que alteraria o conteúdo ao qual o inode está se referindo. Isso não funciona - como você descreveu.fonte