Когда разделяемая библиотека считается «одинаковой» для общего доступа? - PullRequest
7 голосов
/ 25 августа 2011

Мне интересно ... Когда я запускаю программу X, которая использует общую библиотеку A, и во время работы программы я изменяю общую библиотеку на диске и запускаю другую программу Y, которая зависит от того жеобщая библиотека.Будет ли эта программа Y использовать версию общей библиотеки, уже находящуюся в памяти, или она будет загружать отдельный экземпляр общей библиотеки, которая имеет последующие модификации?

Как определяется, следует ли предоставлять общий доступ?загруженная библиотека или перезагрузить ее с диска?

Ответы [ 2 ]

4 голосов
/ 25 августа 2011

Динамический загрузчик просто выполняет обычные старые вызовы open(2) и mmap(2), а карта памяти ударяет по inode, пересчитывает так же, как это делает open fd.Так что, если вы выполните обычный трюк с заменой атомарного файла для библиотеки, запишите изменения в новой копии файла, а затем rename(2) поверх старого имени, все, что будет запущено после этой точки, получит новый индекси новое содержимое, но работающие программы будут продолжать использовать старый инод и старое содержимое.

Если вы измените библиотеку на месте, естественно, любые программы, запущенные после вызова write, получат ваши изменения.Более интересным вопросом является то, что происходит с процессами, которые уже сопоставили его.Ответ, вероятно, либо «система не позволит вам сделать это», либо «не определено, зависит от деталей реализации кэша страницы».Взглянув на реализацию Linux (это то, что я должен передать): динамический загрузчик glibc использует MAP_DENYWRITE для всех своих карт общих библиотек, что не задокументировано, но звучит как будто означает «создать этот файл»немодифицируемый, пока существует отображение ".Тем не менее, я не могу найти ничего в исходниках ядра, которое заставляет MAP_DENYWRITE делать что-либо;это может быть исторический пережиток или что-то подобное.

Он также использует MAP_PRIVATE.http://pubs.opengroup.org/onlinepubs/7908799/xsh/mmap.html говорит, что «не определено, видны ли изменения в базовом объекте, сделанные после отображения MAP_PRIVATE, через отображение MAP_PRIVATE».Таким образом, вы можете или не сможете изменить образ совместно используемой библиотеки под запущенным процессом, в зависимости от деталей реализации кэша страницы.

0 голосов
/ 25 августа 2011

Динамический загрузчик использует mmap(2) для загрузки общих библиотек, поэтому вся магия действительно в mmap(2).

В конкретном случае Linux сопоставления файлов вызывают специфическую для fs операцию mmap(), которая обычно связана с mm/filemap.c:generic_file_mmap(), которая устанавливает vm_ops.fault для сопоставления файлов на mm/filemap.c:filemap_fault(), поэтому магия задерживается до времени ошибки страницы. filemap_fault() пытается найти страницу в кеше, используя find_lock_page().

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