Risposte:
Come accennato da @Kusalananda, in genere gli aggiornamenti vengono eseguiti rimuovendo il vecchio file e creandone uno nuovo con lo stesso nome. Questo creerà effettivamente un nuovo file con un nuovo inode, lasciando il sistema libero di usare quello vecchio fintanto che è aperto.
Come esempio semplificato, cose del genere
rm /bin/cat
cp /new/version/of/cat /bin/cat
creerà un nuovo file logicamente e funziona anche se cat
potrebbe essere in esecuzione. Lo stesso vale per le biblioteche. (Quanto sopra è un esempio, non un modo affidabile per aggiornare un file nel mondo reale.)
Qualcuno potrebbe provare a cambiare il binario sul posto invece di crearne uno nuovo con lo stesso nome. In questo caso, almeno Linux impedisce effettivamente di apportare modifiche a un eseguibile in uso:
window 1 # ./cat
window 2 # echo foobar > cat
-bash: cat: Text file busy
Tuttavia, questo non sembra funzionare con le librerie caricate dinamicamente ...
Ne ho fatto una copia libc.so.6
per il test e l'ho riempito di zeri mentre era in uso:
window 1 /tmp/lib# LD_LIBRARY_PATH=/tmp/lib ldd ./cat
linux-vdso.so.1 (0x00007ffcfaf30000)
libc.so.6 => /tmp/lib/libc.so.6 (0x00007f1145e67000)
/lib64/ld-linux-x86-64.so.2 (0x00007f1146212000)
window 1 /tmp/lib# LD_LIBRARY_PATH=/tmp/lib ./cat
foo
foo
Segmentation fault
(Nel frattempo in un'altra finestra, dopo il foo
, prima del segfault)
window 2 /tmp/lib# dd if=/dev/zero of=libc.so.6 bs=1024 count=2000
Non c'è davvero nulla che il programma stesso possa fare contro questo, dal momento che ho effettivamente modificato il suo codice online.
(Questo probabilmente dipenderà dal sistema, ho testato su Debian Jessie 8.5, Linux 3.16.7-ckt25-2 + deb8u3. I sistemi Windows IIRC in particolare sono ancora più aggressivi nel prevenire la modifica dei file in uso.)
Quindi suppongo che la risposta sia che gli aggiornamenti vengono generalmente eseguiti in modo da evitare qualsiasi problema, e questo è aiutato dagli interni del filesystem. Ma (su Linux) non sembrano esserci garanzie contro le librerie dinamiche effettivamente corrotte.
install
utilità è comunemente usata per cose come questa. Non è necessario esplicitamente rm
il file di destinazione. Inoltre conserva i permessi del file esistente, può fare un backup, impostare una nuova modalità, ecc. Esempio di utilizzo:install /new/version/of/cat /bin/cat
rm
+ cp
era inteso come esempio. Potrebbe anche essere intelligente mettere il nuovo file in posizione atomicamente con una ridenominazione, evitando una breve finestra in cui nessuna versione è disponibile. (Anche se GNU install
non sembra nemmeno farlo, hmpf.)
rm
), allora non è ancora cancellato. Esisterà sul disco e può ancora essere letto da tutti i processi che lo hanno aperto. Verrà eliminato solo quando il conteggio del collegamento reale raggiunge lo zero E il numero di procedure precedenti con il file aperto raggiunge lo zero.
install
utilità non è particolarmente sicura! Sovrascrive il file di destinazione in posizione anziché sostituirlo atomicamente. mv
(con source e dest nella stessa directory, source di solito un file temporaneo) è l'unico modo sicuro per installare i file.
strace
, install
in GNU coreutils scollega il file di destinazione e ne copia uno nuovo al suo posto. Ciò significa che c'è una breve finestra durante la quale il file è parziale. Non imposta il file atomicamente in posizione con una ridenominazione.
I file non verranno "correttamente eliminati" se vengono scollegati mentre sono ancora aperti. Quando vengono chiusi, lo spazio su disco utilizzato verrà nuovamente considerato "libero". Questo vale anche per le applicazioni attualmente in esecuzione e le loro librerie condivise.
L'unica cosa che potrei vedere fallire sarebbe se un programma utilizzato dlopen()
per caricare una libreria condivisa su richiesta, o se il programma dovesse accedere ad altri file su richiesta come dizionari, file di temi o altri file che improvvisamente scomparivano.
Per illustrare: l'esecuzione vim
in una sessione della shell durante l'eliminazione dell'installazione vim
in un'altra sessione della shell non "corromperà" o terminerà la vim
sessione attualmente in esecuzione . Ma alcune cose inizieranno a fallire, come ad esempio il controllo ortografico, che richiede vim
l'apertura dei file nella sua installazione.
ln -sf
quando cambi le librerie, perché-f
ti ha permesso di "sovrascrivere" la destinazione esistente del collegamento simbolico con uno nuovo, senza che sia mai "rotto" (a differenza di unrm
seguito da aln -s
). Quindi, prima del comando, library.so puntava alla versione precedente, ad es. library.so.4 ... dopo il comando, semplicemente indicando library.so.5 (o qualsiasi altra cosa), invece - senza mai , non punta a una libreria valida.