Come aggiornare la libreria condivisa senza crash?


18

Qui dice che è possibile riscrivere un file eseguibile e il processo verrà eseguito correttamente: verrà riletto al riavvio di un processo.

Tuttavia, quando provo a sostituire un file binario mentre il processo è in esecuzione (con scp, da dev a server di test), dice "file occupato". E se sostituisco un file di libreria condivisa (* .so), tutti i processi che lo collegano si arrestano in modo anomalo.

Perchè così? Mi sto perdendo qualcosa? Come posso sostituire i file binari senza interrompere / arrestare in modo anomalo un processo?


Puoi controllare il .sofile usando ldd filename.soper controllare le dipendenze
Rahul Patil,

Conosco le dipendenze. Voglio un modo per sostituire quei file senza influire sui processi in esecuzione. Come suggerisce la domanda collegata
Sam

sono necessari tempi di inattività .. oppure puoi fare così stop app && create symlink of .so && start app
Rahul Patil,

Risposte:


21

Come accennato in Perché un pacchetto software funziona perfettamente anche quando viene aggiornato? , il blocco è posizionato sull'inode e non sul nome file. Quando si carica ed esegue un file binario, il file viene contrassegnato come occupato, motivo per cui viene visualizzato l'errore ETXTBSY (file occupato) quando si tenta di scrivere su di esso.

Ora, per le librerie condivise è leggermente diverso: le librerie ottengono la memoria mappata nello spazio degli indirizzi del processo con mmap(). Sebbene MAP_DENYWRITEpossa essere specificato, almeno Glibc su Linux lo ignora silenziosamente (secondo la pagina man, sentiti libero di controllare le fonti) - controlla questo thread . Quindi in realtà ti è permesso scrivere il file e, dato che è mappato nella memoria, le modifiche sono visibili quasi immediatamente - il che significa che se ci provi abbastanza puoi riuscire a murare la tua macchina sovrascrivendo la libreria.

Il modo corretto di aggiornare quindi è:

  1. rimozione del file, che rimuove il riferimento ai dati dal file system, in modo che non sia accessibile per tutte le applicazioni appena generate che potrebbero voler usarlo, mantenendo i dati accessibili a chiunque lo abbia già aperto (o mappato) ;

  2. creando un nuovo file con contenuti aggiornati.

I processi appena creati utilizzeranno i contenuti aggiornati, le applicazioni in esecuzione accederanno alla versione precedente. Questo è ciò che fa qualsiasi utilità di gestione dei pacchetti sana. Si noti che non è completamente privo di pericoli, ad esempio le applicazioni che caricano dinamicamente il codice (utilizzo dlsym()e amici) riscontreranno problemi se l'API della libreria cambia silenziosamente.

Se vuoi essere davvero sicuro, spegni il sistema, monta il file system da un'altra istanza del sistema operativo, aggiorna e riapri il sistema aggiornato.


6

Un aggiornamento rpm fa lo stesso - con binari e librerie in esecuzione mentre nulla si blocca.

Quindi qual è la differenza:

  1. scollegare il file
  2. scrivere un nuovo file con lo stesso nome

Questo NON sostituirà il file sul posto: l'inode che si riferisce al binario in uso è ancora "occupato" fino al termine dell'ultimo oggetto che lo tiene aperto. Il nuovo file verrà creato con un nuovo numero di inode.

Ora scpo cpproverà a sostituire il file sul posto, il che cambierebbe il contenuto a cui l'inode fa riferimento. Questo non funziona, come hai descritto.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.