Prelink/ru

В этом руководстве рассказывается, как использовать поддержку prelink в Portage 2.0.46 и более поздних версиях.

Что такое Prelink и как он может помочь?
Большинство распространенных приложений используют разделяемые библиотеки. Эти разделяемые библиотеки должны быть загружены в память во время выполнения, при этом различные символьные ссылки должны быть вычислены. Для большинства небольших программ эта динамическая компоновка очень быстрая. Но для программ, написанных на C++ и имеющих множество зависимостей между библиотеками, динамическое связывание может занимать достаточно много времени.

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

Предварительное связывание может сократить время запуска приложений. Например, типичное время загрузки программы KDE можно сократить на целых 50%. Единственное, что необходимо сделать - повторно выполненить prelink каждый раз, когда библиотека обновляется для предварительно связанного исполняемого файла.

Обобщение

 * Предварительное связывание осуществляется с помощью программы, которая, как ни странно, называется . Она изменяет бинарный файл, чтобы ускорить его запуск.
 * Если зависящие от приложения библиотеки меняются после того, как вы подвергли его предварительному связыванию, вам нужно повторно связать приложение, иначе вы потеряете выгоду в скорости. Это означает, что каждый раз, когда вы обновляете через portage пакет, который обновляет библиотеки, они должны быть повторно подвергнуты процессу предварительного связывания.
 * Изменение бинарного файла полностью обратимо. У  есть функция возврата к предыдущему состоянию.
 * Текущие версии Portage могут обрабатывать с помощью  изменения MD5sums и mtimes бинарных файлов.
 * Вам не нужно устанавливать  в вашем файле ; Portage автоматически будет поддерживать prelink, если он находит бинарный файл prelink.

Установка программ
Сначала вам нужно установить утилиту. Процесс emerge автоматически проверяет, может ли ваша система безопасно использовать предварительное связывание.

Ряд людей получают ошибки в при установке prelink из-за неудавшихся тестов. Тесты были введены из соображений безопасности, поведение prelink не предсказуемо, если вы отключите их. Ошибки emerge обычно зависят только от основных пакетов; Binutils, gcc и glibc. Попробуйте повторно пересобрать эти пакеты в этом случае.

Если у вас есть набор шагов, которые приводят к такой же ошибке emerge на другой системе, пожалуйста проверьте Bugzilla и создайте отчет об ошибке, если о ней еще не сообщалось.

Подготовка системы
Также убедитесь, что вы "не" установили -fPIC в «CFLAGS/CXXFLAGS». Если вы это сделали, вам нужно будет полностью пересобрать всю систему без него.

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

К сожалению, вы не можете предварительно связать файлы, которые были скомпилированы старыми версиями binutils. Большинство таких приложений поставляются только в виде предварительно скомпилированных бинарных пакетов, которые установлены в. Создание следующего файла укажет prelink не пытаться связать их.

Использование Prelink
Я использую следующую команду для связывания всех двоичных файлов в каталогах, заданных.

Задание Cron для Prelink
Установите, а затем установите задание cron в. Чтобы включить его, отредактируйте файл конфигурации. Он будет запускать prelink ежедневно в фоновом режиме, спасая вас от необходимости запуска команды вручную.

Ускорение KDE после предварительного связывания
Время загрузки KDE может быть значительно уменьшено после предварительного связывания. Если вы сообщите KDE, что он был предварительно связан, это отключит загрузку  (поскольку он больше не требуется), что еще больше ускорит KDE.

Установите  в, чтобы сообщить KDE о предварительном связывании.

Удаление prelink
Если вы передумаете использовать предварительное связывание, прежде чем удалять prelink, сначала нужно удалить prelink cronjob из и. Затем вам придется удалить предварительное связывание из всех двоичных файлов:

Наконец, удалите сам пакет :

"Cannot prelink against non-PIC shared library" ("Невозможно осуществить предварительное связывание с не-PIC-разделяемой библиотекой")
Причина этой проблемы связана с плохо скомпилированными разделяемыми библиотеками, которые были скомпилированы без gcc опции -fPIC для всех их объектных файлов.

Библиотеки, которые не были исправлены или не могут быть исправлены:


 * Библиотеки в wine пакете, включая winex. Предварительное связывание в любом случае не ускорит выполнение исполняемых файлов MS Windows.
 * Библиотека в media-video/mjpegtools,.
 * Библиотеки Nvidia OpenGl, . Из соображенияй производительности они были скомпилированы без поддержки PIC.

Если ваша проблемная библиотека не указана в списке, пожалуйста, сообщите об этом, желательно в виде patch'а добавив  в соответствующие CFLAGS.

Когда я применяю предварительное связывание к моей системе, некоторые статические двоичные файлы больше не работают
Когда дело касается glibc, нет такого понятия, как 100% статический двоичный файл. Если вы статически компилируете двоичный файл с помощью glibc, он все равно может зависеть от других системных файлов. Ниже приводится объяснение Дика Хауэлла (Dick Howell),

"Полагаю, идея состоит в том, что все должно находиться в загруженном файле, поэтому ничего не зависит от локальных библиотек целевой системы. К сожалению, в случае с Linux, и я думаю, с чем бы то ни было, что использует GLIBC, это не совсем так. Возьмем к примеру «libnss» (переключатель службы имен, некоторые люди называют его cbcntvjq сетевой системой безопасности), которая предоставляет функции для доступа к различным базам данных для аутентификации, сетевой информации и других вещей. Предполагается, что прикладные программы не зависят от отдельно настроенного реального сетевого окружения машины. Хорошая идея, но изменения в GLIBC могут привести к проблемам при ее загрузке. И вы не можете статически связать «libnss», поскольку она настроена для каждой машины отдельно. Проблема возникает, я думаю, в основном из-за статического связывания других GLIBC библиотек, в частности «libpthread», «libm» и «libc», из которых происходят несовместимые вызовы функций «libnss»."

Prelink прерывается с "prelink: dso.c: 306: fdopen_dso: Assertion 'j
k' failed." ===

Это известная проблема, любезно диагностированная здесь. Prelink не может справиться с UPX-сжатыми исполняемыми файлами. Начиная с prelink-20021213, нет способа это исправить, кроме как скрыть исполняемые файлы во время предварительного связывания. Смотрите раздел выше для простого способа сделать это.

Я использую grsecurity, и кажется, что предварительное связывание не работает.
Чтобы предварительно связать систему с grsecurity с использованием рандомизированной базы mmap, необходимо включить параметр «randomized mmap base» OFF для. Это можно сделать с помощью утилиты, но это необходимо сделать, когда файл не используется (например, загрузиться с компакт-диска для восстановления).

Prelink падает с ошибкой "prelink: Can't walk directory tree XXXX: Too many levels of symbolic links" ("prelink: не удается обойти дерево каталогов XXXX: слишком много уровней символических ссылок")
Ваши символьные ссылки вложены слишком глубоко. Это происходит, когда символьная ссылка указывает на себя. Например, наиболее распространенным является. Чтобы это исправить, вы можете найти символьную ссылку вручную или использовать утилиту, предоставленную пакетом :

Более подробную информацию можно найти в Bugzilla и в этом сообщении на Форуме.

Заключение
Предварительное связывание может значительно ускорить время запуска для ряда крупных приложений. Его поддержка встроена в Portage. Также предварительное связывание безопасно, так как вы всегда сможете его отменить для любого двоичного файла при возникновении проблем. Просто помните, что при обновлении glibc или других библиотек, с которыми вы произвели предварительное связывание, вам нужно повторно запустить ! Короче, удачи!