2011-08-24 9 views
7

Mi chiedo ... Quando avvierò un programma X che utilizza una libreria condivisa A e mentre il programma è in esecuzione, modifico la libreria condivisa sul disco ed eseguo un altro programma Y che dipende dalla stessa condivisione biblioteca. Il programma Y utilizzerà la versione già in memoria della libreria condivisa o caricherà un'istanza distinta della libreria condivisa con le modifiche successive?Quando una libreria condivisa è considerata "uguale" ai fini della condivisione?

Come viene determinato se condividere o meno una libreria caricata o ricaricarla dal disco?

risposta

4

Il caricatore dinamico fa solo regolare vecchi open(2) e mmap(2) chiamate e una mappa di memoria urti refcounts inode stesso modo un fd aperta fa. Quindi se fai il solito trucco di sostituzione del file atomico per la libreria, scrivi le tue modifiche in una nuova copia del file e poi rename(2) sopra il vecchio nome, tutto ciò che è iniziato dopo quel punto preleverà il nuovo inode e il nuovi contenuti, ma i programmi in esecuzione continueranno a utilizzare il vecchio inode e il vecchio contenuto.

Se si modifica la libreria in posizione, naturalmente tutti i programmi avviati dopo la chiamata write rileveranno le modifiche. La domanda più interessante è che cosa succede ai processi che l'hanno già mappato. La risposta è probabilmente "il sistema non ti permetterà di farlo" o "non specificato, dipende dai dettagli dell'implementazione della cache di pagina". Poking casualmente sull'implementazione Linux (che è quello che ho a disposizione): Il caricatore dinamico glibc usa MAP_DENYWRITE per tutte le sue mappe di libreria condivise, che non sono documentate ma suoni come se significasse "rendere questo file non modificabile mentre esiste la mappatura" . Tuttavia, non riesco a trovare nulla nei sorgenti del kernel che rende MAP_DENYWRITEdo nulla; potrebbe essere una traccia storica o qualcosa di simile.

Utilizza anche MAP_PRIVATE. http://pubs.opengroup.org/onlinepubs/7908799/xsh/mmap.html afferma che "Non è specificato se le modifiche all'oggetto sottostante eseguite dopo che il mapping MAP_PRIVATE è stato stabilito sono visibili tramite il mapping MAP_PRIVATE." Quindi potresti o potresti non essere in grado di modificare un'immagine di una libreria condivisa sotto un processo in esecuzione, a seconda dei dettagli dell'implementazione della cache di pagina.

0

Il caricatore dinamico utilizza mmap(2) per caricare librerie condivise, quindi tutta la magia è davvero in mmap(2).

Nel caso specifico di Linux, mappature di file chiamare un mmap() specifica operazione-fs, che di solito è collegato a mm/filemap.c:generic_file_mmap(), che imposta la vm_ops.fault per la mappatura file mm/filemap.c:filemap_fault(), quindi la magia è in ritardo in tanto errore di pagina. filemap_fault() tenta di trovare la pagina nella cache della pagina utilizzando find_lock_page().

mmap() → fs_file_ops.mmap() → generic_file_mmap() → file_vm_ops.fault = filemap_fault() 
page fault → filemap_fault() → find_lock_page() 
+0

questo in realtà non risponde alla domanda – zwol

Problemi correlati