2011-08-24 13 views
7

Me pregunto ... Cuando estoy comenzando un programa X que usa una biblioteca compartida A, y mientras el programa se ejecuta, modifico la biblioteca compartida en el disco, y ejecuto otro programa Y que depende de la misma fuente compartida biblioteca. ¿Ese programa Y usará la versión ya en la memoria de la biblioteca compartida, o cargará una instancia distinta de la biblioteca compartida que tenga las modificaciones posteriores?¿Cuándo se considera que una biblioteca compartida es "la misma" para compartir?

¿Cómo se determina si compartir o no una biblioteca cargada o volver a cargarla desde el disco?

Respuesta

4

El cargador dinámico sólo hace regulares viejos open(2) y mmap(2) llamadas, y un mapa de memoria choca refcounts inode la misma forma en que un fd abierta hace. Por lo tanto, si realiza el truco habitual de reemplazo de archivos atómicos para la biblioteca, escriba los cambios en una nueva copia del archivo y luego rename(2) sobre el nombre anterior; cualquier cosa que se inicie después de ese punto recogerá el nuevo inodo y el nuevos contenidos, pero los programas en ejecución seguirán usando el antiguo inodo y los contenidos anteriores.

Si modifica la biblioteca en su lugar, naturalmente cualquier programa iniciado después de la llamada write recogerá los cambios. La pregunta más interesante es qué sucede con los procesos que ya lo tuvieron asignado. La respuesta probablemente sea "el sistema no te dejará hacer eso" o "no especificado, depende de los detalles de la implementación del caché de página". Meter casualmente en la implementación de Linux (que es lo que tengo que entregar): el cargador dinámico glibc usa MAP_DENYWRITE para todos sus mapas de bibliotecas compartidas, lo cual no está documentado pero suena como "hace que este archivo no se pueda modificar mientras existe la asignación" . Sin embargo, no puedo encontrar nada en las fuentes del núcleo que hace MAP_DENYWRITEhacer nada; podría ser un vestigio histórico o algo así.

También utiliza MAP_PRIVATE. http://pubs.opengroup.org/onlinepubs/7908799/xsh/mmap.html dice que "No se especifica si las modificaciones en el objeto subyacente después de que se establece la asignación MAP_PRIVATE son visibles a través de la asignación MAP_PRIVATE". Por lo tanto, puede o no ser capaz de modificar una imagen de biblioteca compartida debajo de un proceso en ejecución, dependiendo de los detalles de la implementación de la memoria caché de página.

0

El cargador dinámico utiliza mmap(2) para cargar bibliotecas compartidas, por lo que toda la magia está realmente en mmap(2).

En el caso específico de Linux, asignaciones de archivo llaman una operación mmap()-fs específica, que por lo general está conectado a mm/filemap.c:generic_file_mmap(), que establece el vm_ops.fault para la asignación de archivos a mm/filemap.c:filemap_fault(), por lo que la magia se retrasa en cuando error de página. filemap_fault() intenta encontrar la página en la memoria caché de la página usando 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

Esto en realidad no responde la pregunta – zwol

Cuestiones relacionadas