Переназначение разделяемых библиотек


Для некоторых программных компонентов предпочтительнее использовать конкретные библиотеки, отличные от тех, что используются остальной системой. Например, стандартная библиотека языка С — libc. Вы можете завести отдельную копию libc со специальными функциями, предоставляемыми только определенной программе, и заставить эту программу работать со специальной версией libc, при этом все другие программы будут использовать стандартную библиотеку libc. Операционная система FreeBSD позволяет подменять любую разделяемую библиотеку для любого приложения. Хотя это и кажется странным, тем не менее такая возможность полезна в особых случаях. Программа rtld(1) может обмануть клиентскую программу, если такое поведение ей предписывается файлом /etc/libmap.сonf.

Предположим, что сервер базы данных показывает лучшую производительность при использовании конкретной библиотеки реализации многопоточной модели исполнения, не являющейся библиотекой по умолчанию. Программа ldd(1) может сообщить, что программа предполагает обращаться к разделяемой библиотеке libpthread (она же — libthr), но у вас может появиться желание использовать библиотеку libkse. В этом случае вам не требуется подменять библиотеку, с которой работает остальная часть системы. Когда программа сообщает: «Мне нужна библиотека libpthread», — нужно, чтобы утилита rtld(1) ответила: «Она здесь» и подключила бы библиотеку libkse. Такую подмену можно настроить и для всей системы в целом, и для отдельной программы с определенным именем, и даже для программ, расположенных в определенном каталоге.

Содержимое файла /etc/libmap.conf поделено на две колонки. Первая колонка содержит имя разделяемой библиотеки, которую запрашивает программа, а вторая — имя разделяемой библиотеки, которая будет использована фактически. Все изменения вступают в силу при следующем запуске программы — не требуется ни перезагружать систему, ни перезапускать демоны. Например, ниже системе предписывается, чтобы программам, запрашивающим библиотеку libpthread, предлагалась библиотека libkse. Такие подмены глобального характера должны быть описаны в начале файла libmap.conf:

libpthread.so.2         libkse.so.2
libpthread.so           libkse.so

«Могу ли я получить библиотеку libpthread.so.2?» «Да, конечно, вот вам libkse.so.2.»

Глобальное переназначение библиотек — это слишком смелый шаг, который заставит системных администраторов заговорить о вас; переназначение библиотек для отдельных программ не так впечатляет, зато оно способно решить проблем больше, чем принести. Для этого достаточно просто указать имя программы и полный путь к ней в квадратных скобках, но в этом случае переназначение будет работать только при вызове программы по полному пути к ней. Если определить только имя программы, переназначение будет работать всякий раз, когда запускается какая-либо программа с данным именем. Например, ниже производится переназначение для csup(8), в результате которого при запуске программы с указанием полного пути к ней вместо библиотеки libpthread она будет использовать библиотеку libkse:

[/usr/bin/csup]
libpthread.so.2           libkse.so.2
libpthread.so             libkse.so

Как убедиться, что переназначение работает? Конечно, с помощью команды ldd(1):

Здесь видно, что когда программа /usr/bin/csup запросит libpthread.so.2 (1), rtld(1) свяжет ее с библиотекой libkse.so.2 (2). Однако в этом примере мы указали полный путь к программе. Попробуем вызвать ldd для csup без указания полного пути к ней:

# cd /usr/bin
# ldd csup

csup:
        libcrypto.so.5 => /lib/libcrypto.so.5 (0x2808f000)
        libz.so.3 => /lib/libz.so.3 (0x281b8000)
        libpthread.so.2 => /lib/libpthread.so.2 (0x281c9000)
        libc.so.7 => /lib/libc.so.7 (0x281ef000)

Если перейти в каталог /usr/bin и передать утилите ldd программу csup без полного пути к ней, то rtld не получит полный путь к исполняемому файлу csup(1). Поскольку в /etc/libmap.conf указано, что подстановка выполняется для полного имени /usr/bin/csup, то при обращении по одному имени csup в ответ на запрос библиотеки libpthread.so.2 будет предложена библиотека libpthread.so.2.

Если нужно, чтобы программа использовала альтернативную библиотеку независимо от того, вызывается она по полному имени или по базовому, то в квадратных скобках нужно указать только имя программы:

[csup]
libpthread.so.2           libkse.so.2
libpthread.so             libkse.so

Подобным же образом можно определить подстановку библиотек для всех программ в каталоге, указав в квадратных скобках имя каталога с завершающим символом слэша. В следующем примере определяется подстановка альтернативной библиотеки для всех программ в каталоге:

[/home/oracle/bin/]
libpthread.so.2           libkse.so.2
libpthread.so             libkse.so

С помощью файла libmap.conf можно выполнять подстановку разделяемых библиотек произвольным образом. Обычно этот прием применяется для подстановки библиотек реализации многопоточной модели исполнения (и иногда для программ, запускаемых в режиме совместимости с Linux), тем не менее он позволит вам «подсовывать» своим программам любые библиотеки. Разумеется, настроить библиотеки можно и с помощью переменной окружения LD_LIBRARY_PATH, но это касается только тех пользователей, кто может задать значение этой переменной.

Комментарии запрещены.