Se o usuário trabalha em um aplicativo que está vinculado dinamicamente e o sistema está sendo atualizado, existe algum mecanismo de proteção que evita a corrupção do aplicativo?
Ou depende da aplicação?
upgrade
dynamic-linking
sevo
fonte
fonte
ln -sf
ao trocar de bibliotecas, porque isso-f
permite que você "sobrescreva" o destino existente do link simbólico por um novo, sem que ele nunca seja "quebrado" (diferente de se vocêrm
seguisse aln -s
) Portanto, antes do comando, library.so apontou para a versão antiga, por exemplo. library.so.4 ... após o comando, ele simplesmente apontou para library.so.5 (ou qualquer outro) em vez - sem nunca não apontando para uma biblioteca válido.Respostas:
Conforme mencionado por @Kusalananda, geralmente as atualizações são feitas removendo o arquivo antigo e criando um novo com o mesmo nome. Na verdade, isso criará um novo arquivo com um novo inode, deixando o sistema livre para usar o antigo enquanto estiver aberto.
Como um exemplo simplificado, coisas como
criará um arquivo logicamente novo e funcionará mesmo que
cat
esteja em execução. O mesmo vale para as bibliotecas. (O exemplo acima é um exemplo, não uma maneira robusta de atualizar um arquivo no mundo real.)Alguém poderia tentar alterar o binário no local em vez de criar um novo com o mesmo nome. Nesse caso, pelo menos o Linux realmente impede fazer alterações em um executável em uso:
No entanto, isso não parece funcionar com bibliotecas carregadas dinamicamente ...
Fiz uma cópia
libc.so.6
para teste e a preenchi com zeros enquanto estava em uso:(Enquanto isso, em outra janela, após o
foo
, antes do segfault)Não há realmente nada que o próprio programa possa fazer contra isso, desde que efetivamente editei seu código online.
(Isso provavelmente dependerá do sistema, testei no Debian Jessie 8.5, Linux 3.16.7-ckt25-2 + deb8u3. Os sistemas Windows IIRC em particular são ainda mais agressivos ao impedir a modificação de arquivos em uso.)
Portanto, acho que a resposta é que as atualizações geralmente são feitas de maneira a evitar problemas, e isso é ajudado pelos componentes internos do sistema de arquivos. Mas (no Linux) não parece haver nenhuma proteção contra bibliotecas dinâmicas realmente corrompidas.
fonte
install
utilitário é comumente usado para coisas como esta. Você não precisa explicitamenterm
o arquivo de destino. Além disso, ele preserva as permissões do arquivo existente, pode fazer uma cópia de segurança, definir um novo modo, etc. Exemplo de uso:install /new/version/of/cat /bin/cat
rm
+cp
foi usado como exemplo. Também pode ser inteligente colocar o novo arquivo no lugar atomicamente com uma renomeação, para evitar uma pequena janela na qual nenhuma versão está disponível. (Embora GNUinstall
não parece mesmo fazer isso, hmpf.)rm
), ele ainda não será excluído. Ele existirá no disco e ainda poderá ser lido por todos os processos que o abrirem. Ele será excluído apenas quando a contagem de links físicos atingir zero E o número de precesses com o arquivo aberto atingir zero.install
utilitário é especificamente inseguro! Ele substitui o arquivo de destino no lugar, em vez de substituí-lo atomicamente.mv
(com origem e destino no mesmo diretório, fonte geralmente um arquivo temporário) é a única maneira segura de instalar arquivos.strace
,install
no GNU coreutils desvincula o arquivo de destino e depois copia um novo em seu lugar. O que significa que existe uma janela curta durante a qual o arquivo é parcial. Ele não define o arquivo atomicamente no lugar com uma renomeação.Os arquivos não serão "excluídos corretamente" se forem desvinculados enquanto ainda estão abertos. Quando eles estiverem fechados, o espaço em disco que eles usaram será considerado "livre" novamente. Isso vale para aplicativos em execução no momento e suas bibliotecas compartilhadas também.
A única coisa que eu via falha seria se um programa usasse
dlopen()
uma biblioteca compartilhada sob demanda ou se o programa precisasse acessar outros arquivos sob demanda, como dicionários, arquivos de temas ou outros arquivos que desapareceram repentinamente.Para ilustrar: A execução
vim
em uma sessão de shell e a instalação devim
outra sessão de shell não "corromperão" nem encerrarão avim
sessão atualmente em execução . Mas algumas coisas começam a falhar, como a verificação ortográfica, por exemplo, que requervim
a abertura de arquivos em sua instalação.fonte