Perché un pacchetto software funziona perfettamente anche quando viene aggiornato?


29

Supponiamo che io stia eseguendo un software e quindi eseguo il gestore pacchetti per aggiornare il software, noto che Linux non interrompe il processo in esecuzione per l'aggiornamento del pacchetto, ma continua a funzionare correttamente. Come fa Linux?

Risposte:


35

Il motivo è che Unix non blocca un file eseguibile mentre viene eseguito o anche se gli piace Linux, questo blocco si applica all'inode, non al nome del file. Ciò significa che un processo che lo tiene aperto sta accedendo agli stessi (vecchi) dati anche dopo che il file è stato eliminato (in realtà non collegato) e sostituito da uno nuovo con lo stesso nome che è essenzialmente ciò che fa un aggiornamento del pacchetto.

Questa è una delle principali differenze tra Unix e Windows. Quest'ultimo non è in grado di aggiornare un file bloccato poiché manca un livello tra nomi file e inode, il che rende una seccatura maggiore aggiornare o addirittura installare alcuni pacchetti poiché di solito richiede un riavvio completo.


10
Per chiarire, sotto Linux non è possibile modificare un file eseguibile mentre è in esecuzione. Ma puoi scollegare il file e sostituirlo con un nuovo file con lo stesso nome.
cjm

Sotto Linux, è possibile modificare un file eseguibile mentre è in esecuzione. Il risultato sarebbe probabilmente imprevedibile, a meno che tu non sappia davvero cosa stai facendo. Aggiunto il punto "stesso nome" che non è stato esplicitamente dichiarato.
jlliagre,

4
@jlliagre A meno che non sia frainteso, non puoi per quanto ne so: sprunge.us/egiR
Chris Down

2
Una cosa bella di NFTS però: se si esegue una ridenominazione dalla riga di comando o un altro programma, è possibile posizionare un file con lo stesso nome e non influirà sui programmi che hanno il file originale aperto. (il comando di rinomina in explorer non funziona per questo)
Steffan Donal

1
@cjm Hai ragione riguardo alla protezione "testo file occupato" su Linux, risposta aggiornata. In Solaris non esistono restrizioni di questo tipo con cui ho più familiarità. Tuttavia, puoi comunque modificare le librerie condivise con entrambi i sistemi operativi.
jlliagre,

18

Gli eseguibili vengono generalmente aperti una volta, collegati a un descrittore di file e non hanno un descrittore di file al loro binario riaperto durante un singolo periodo di esecuzione. Ad esempio, se si esegue bash, in exec()genere viene creato un descrittore di file per l'inode a cui fa riferimento /bin/bashuna sola volta alla chiamata.

Questo spesso significa che per i semplici binari che non tentano di rileggersi durante l'esecuzione (usando il percorso con cui sono stati invocati), il contenuto memorizzato nella cache rimane valido come inode pendente. Ciò significa che esiste essenzialmente una replica della versione precedente dell'eseguibile.

In casi più complessi, ciò può causare problemi. Ad esempio, un file di configurazione può essere aggiornato e successivamente riletto, oppure il programma può rieseguirsi tramite il percorso da cui è stato eseguito. Ci possono anche essere problemi se i programmi sono interconnessi e uno viene eseguito prima dell'aggiornamento e uno dopo (possibilmente dal primo programma). Questo vale anche per alcune librerie.

Per casi d'uso semplici, tuttavia, è sicuro eseguire l'aggiornamento senza riavviare il processo.


1
L'altro pericolo, anche in casi semplici, è che, poiché l'applicazione in esecuzione utilizza una copia cache del file binario, fino a quando non si riavvia manualmente l'applicazione, è ancora in esecuzione la versione precedente del codice. Mentre questo non dovrebbe importare la maggior parte del tempo; se l'aggiornamento includeva correzioni di sicurezza, nonostante l'installazione della patch, il sistema è ancora vulnerabile perché la versione precedente è ancora in esecuzione.
Dan Neely,

1
Temo che il tuo primo paragrafo sia inesatto. I kernel Unix / Linux non caricano i programmi eseguibili contemporaneamente ma la memoria li mappa. Ciò significa che solo le pagine effettivamente utilizzate alla fine arrivano alla RAM. Questo è il punto centrale della protezione "File di testo occupato" sotto Linux. Non è garantito che una parte di un eseguibile non verrà letta a lungo dopo il suo lancio. Inoltre alcune pagine non verranno mai caricate per programmi abbastanza grandi e questo è ancora più vero per le librerie caricate dinamicamente. Ad esempio il bashbinario è di circa 200 pagine 4K, non sono sicuro che siano tutte utilizzate in una sessione media.
jlliagre,

@jlliagre Stavo parlando ialloc()di una struttura del kernel in lettura, non della mappatura della memoria delle pagine stesse. Non ho ragione nel pensare che sui moderni filesystem ext *, l'inode sia infine coerente nel kernel (e all'interno del sottosistema VM)?
Chris Down,

Non vi è alcuna garanzia che parti del contenuto eseguibile non vengano lette a lungo dopo l'esecuzione, e non vi è alcuna garanzia che le stesse pagine non verranno lette di nuovo dopo un po 'durante il tempo di esecuzione.
jlliagre,

@jlliagre Esatto, ma non intendevo questo. Forse ho sminuito un po 'le parole nella mia risposta, cercherò di chiarire ciò che intendevo dire.
Chris Down,
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.