АЛЕКСАНДР ПРОКОШЕВ
Компиляция FreeBSD
Перекомпиляция ядра и самой операционной системы FreeBSD – часть непрерывного процесса обеспечения безопасности интернет-сервера, и хотя у новичка в мире открытых исходников слова «компиляция ядра операционной системы» обычно вызывают благоговейное преклонение перед произносящим их, этот процесс на самом деле не является слишком сложным и тем более таинственным. В этой статье я опишу обычный порядок перекомпиляции системы, ее ядра, а также основные опции и параметры команды make, используемые в процессе компиляции для систем, основанных на процессорах семейства Intel x86. На вашей машине должны быть установлены инструменты разработки – gcc, make и все соответствующие библиотеки и заголовочные файлы.
Исходные тексты операционной системы обычно находятся в каталоге /usr/src. Для их обновления до текущей версии чаще всего используется программа cvsup, устанавливаемая из коллекции пакетов FreeBSD. cvsup является разновидностью CVS [2] (concurrent versions system, одна из широко распространенных систем управления версиями программ, используемых для групповой разработки программного обеспечения. СVS обеспечивает подмножество ее функций, необходимое для синхронизации локальных файлов с файлами, расположенными на master-сервере cvsup. При работе cvsup передает только различия (diffs) между измененными со времени последнего обновления файлами, а также может использовать компрессию потока (с использованием zlib), что позволяет этому методу обновления существенно выигрывать в производительности и нагрузке на канал по сравнению, например, c FTP.
Данная программа вызывается с параметром, указывающим местоположение файла, описывающего следующие основные параметры:
- местонахождение исходных текстов OS на локальном винчестере;
- имя сервера, на котором расположен репозиторий с исходными текстами, соответствующими текущей версии;
- части операционной системы (например, игры, библиотеки, ядро или вся система целиком), подлежащие обновлению.
Рассмотрим подробно два параметра – default tag и список коллекций для обновления. Параметр default tag указывает, до какой ветки FreeBSD вы хотите производить апгрейд. Возможные варианты:
- . (точка) – FreeBSD-current. FreeBSD «с переднего края». Не рекомендуется тем, кто только осваивает процесс перекомпиляции.
- RELENG_5_0 – FreeBSD 5.0. Ветка 5.0-RELEASE, используется для критических багфиксов и патчей системы безопасности.
- RELENG_4. Ветка FreeBSD-4.x. Сейчас это FreeBSD-STABLE. Основная ветвь развития четвертой версии системы.
- RELENG_4_7. FreeBSD-4.7-RELEASE, используется для критических багфиксов и патчей системы безопасности.
- RELENG_4_6. FreeBSD 4.6 и 4.6.2, используется для критических багфиксов и патчей системы безопасности.
- RELENG_4_5. FreeBSD 4.5, используется для критических багфиксов и патчей системы безопасности.
- RELENG_4_4. FreeBSD 4.4, используется для критических багфиксов и патчей системы безопасности.
- RELENG_4_3. FreeBSD 4.3, используется для критических багфиксов и патчей системы безопасности.
- RELENG_3. Ветка FreeBSD-3.x. Сейчас это 3.x-STABLE. Основная ветвь развития третьей версии системы.
- RELENG_2_2. Ветка FreeBSD-2.2.x. Устаревшая ветвь.
Чем отличается RELEASE от STABLE? Очень просто: STABLE – это то, что получается из RELEASE в процессе его (релиза) технического сопровождения, то есть исправления ошибок и латания обнаруженных дыр в безопасности. Отдельным пунктом здесь стоит версия системы, обозначаемая тегом RELENG_4, которая представляет собой «стабильную ветвь разработки». Рано или поздно на основе этой версии будет выпущена версия 4.8-RELEASE (RELENG_4_8_0_RELEASE), от которой, в свою очередь, отойдет 4.8-STABLE (RELENG_4_8).
Переходим к списку коллекций. cvsup понимает следующие коллекции, относящиеся к исходным текстам операционной системы:
- src-all – Полное дерево исходников.
- src-base – Базовые программы.
- src-bin – Программы в /usr/src/bin – то, что после установки находится в /bin.
- src-contrib – Contributed software, в том числе awk, gcc, tcpdump и многое другое, без чего не обойтись.
- src-etc – То, что с помощью mergemaster"а устанавливается в /etc.
- src-games – Игры.
- src-gnu – GNU software.
- src-include – .h-файлы для помещения в /usr/include.
- src-kerberos5 – Kerberos 5.
- src-kerberosIV – Kerberos 4.
- src-lib – Исходники системных библиотек.
- src-libexec – Некоторые демоны. Складываются в /usr/libexec.
- src-release – Инструменты для построения дистрибутива.
- src-sbin – Будущее содержимое /sbin.
- src-share – Будущее содержимое /usr/share.
- src-sys – Исходники ядра.
- src-tools – Инструменты для тестирования и поддержки системы. Не собираются во время buildworld.
- src-usrbin – Будущее содержимое /usr/bin.
- src-usrsbin – Будущее содержимое /usr/sbin.
- src-crypto src-eBones src-secure src-sys-crypto – Криптоподсистема.
Еще раз подчеркну, что коллекция src-all включает в себя все остальные коллекции, так что если в sup-файле вы указали «src-all», нет надобности указывать еще какие-либо коллекции. С другой стороны, FreeBSD Handbook [1] рекомендует не обновлять userspace программы отдельно от ядра и наоборот, так как это может привести к неработоспособности программ из-за несоответствий структур данных (простой пример – команда ps, часто не работающая с ядром, версия которого не соответствует версии остальной системы).
Полностью формат sup-файла описан в документации по cvsup. Далее в этой статье я предполагаю, что параметр default tag установлен в значение «RELENG_4», соответствующий версии системы 4.x-STABLE, и производится обновление системы целиком (используется тег src-all). При этом наш sup-файл имеет примерно следующий вид:
--== cut /etc/cvsupfile.sys ==--
# Файл обновления системы
*default host=cvsup5.FreeBSD.org
*default base=/usr
*default prefix=/usr
*default release=cvs
*default tag=RELENG_4
*default delete use-rel-suffix compress
src-all
# src-base
# src-bin
# src-contrib
# src-etc
# src-games
# src-gnu
# src-include
# src-kerberos5
# src-kerberosIV
# src-lib
# src-libexec
# src-release
# src-sbin
# src-share
# src-sys
# src-tools
# src-usrbin
# src-usrsbin
# src-crypto
# src-eBones
# src-secure
# src-sys-crypto
--== end cut ==--
Запускаем cvsup:
--== cut here ==--
ice.root# cvsup /etc/cvsupfile.sys
Connected to cvsup5.FreeBSD.org
Updating collection src-all/cvs
Edit src/etc/Makefile [выводимые сообщения опущены]
Edit src/share/misc/pci_vendors
Finished successfully ice.root#
--== end cut ==--
После успешного завершения работы cvsup в каталоге /usr/src нашего компьютера находятся исходные тексты, соответствующие текущему содержанию CVS-репозитория ветки STABLE четвертого релиза FreeBSD.
Теперь переходим к компиляции.
Сначала просмотрим файл, настройки которого влияют на конфигурацию и производительность получаемой в результате системы – /etc/make.conf (или /etc/defaults/make.conf). В нем вы можете задать параметры оптимизации для компилятора, указать, компилировать ли профилировочные версии библиотек, sendmail, поставляемый с системой, perl, а также некоторые другие опции. Интересное замечание насчет параметров оптимизации: FreeBSD Handbook [1] рекомендует выставлять флаг оптимизации «-O», но ничто не мешает вам выставить, к примеру «-O3 -march=i686», хотя, конечно, это скажется на времени компиляции. Еще одно важное замечание: если вы производите апгрейд с версии FreeBSD 4.7-RELEASE или ниже на 4-STABLE, обязательно выставьте параметр 2COMPAT3X» файла /etc/make.conf в значение «yes», иначе при запуске программ, скомпилированных для FreeBSD 3.x (одной из таких программ является JDK 1.1.8, содержащийся в ports), вы увидите сообщение динамического редактора связей о ненайденном символе __stderrp в системных библиотеках.
Начнем с конфигурации ядра. Традиционно в 4.3BSD-based системах, к которым относится и FreeBSD, конфигурация ядра описывается в текстовом файле, который затем с помощью команды config преобразуется в h-файлы и Makefile, используемые непосредственно инструментами компиляции. Примеры файлов конфигурации находятся в каталоге /usr/src/sys/i386/conf и называются GENERIC и LINT. Для создания своей конфигурации скопируйте файл GENERIC в файл, к примеру:
MYCONF:
cd /usr/src/sys/i386/conf
cp GENERIC MYCONF
и приступайте к его редактированию. Значения опций довольно подробно описаны в файле LINT, и я не буду повторно описывать их здесь. Естественно, вы должны отчетливо представлять себе аппаратную конфигурацию вашей машины. И еще один совет: на первых порах случается всякое, поэтому лучше вносить серьезные изменения в конфигурацию ядра той же версии, под которой в данный момент работает ваш компьютер, то есть до обновления исходников через cvsup. Такой подход имеет два преимущества:
- исключается полная перекомпиляция системы (то есть make buildworld не выполняется – только make buildkernel, так как установленная система той же версии, что и собираемое ядро), что значительно уменьшает время итерации;
- больше возможности сохранить работоспособность системы при загрузке со старым ядром в случае неработоспособности вновь собранного из-за того же самого соответствия версии системы версии ядра.
После завершения редактирования перейдите в каталог /usr/src и дайте команду сборки системы: cd /usr/src make buildworld. Время выполнения этой команды зависит от заданных ранее опций компиляции и может составить от часа до нескольких часов. Если вы компилируете на многопроцессорной машине, имеет смысл выполнять make с ключом -j, где n – количество процессоров:
make -j4 buildworld
Внимание! Для сборки системы вам потребуется около 300 Мб свободного места на разделе файловой системы, содержащем каталог /usr/obj.
После окончания сборки системы остается только скомпилировать ядро:
make buildkernel KERNCONF=MYCONF
Здесь MYCONF – имя того самого файла конфигурации ядра в каталоге /usr/src/sys/i386/conf, который вы недавно редактировали. Обратите внимание, что команда make выполняется в каталоге /usr/src, а имя файла конфигурации передается ей без пути до него. После успешного завершения работы make перейдите в однопользовательский режим:
shutdown now
и, вновь войдя в каталог /usr/src cd /usr/src, выполните три заключительные команды:
make installkernel KERNCONF=MYCONF
make installworld
fastboot
При выполнении make installkernel ваше нынешнее ядро будет скопировано в файл /kernel.old, а модули – в каталог /modules.old. Это даст вам шанс все же запустить систему со старым ядром, если новое по какой-либо причине окажется неработоспособным.
Совет: если вы компилировали ядро самый первый раз (то есть то, которое перед выполнением make installkernel находится в файле /kernel, заведомо работоспособно), перед make installkernel скопируйте его на всякий случай, допустим, в /kernel.stable, чтобы оно не затерлось последующими выполнениями make installkernel. У вас будет возможность впоследствии загрузить его из командной строки начального загрузчика OS вместо ядра по умолчанию /kernel. Описание работы с командами начального загрузчика выходит далеко за рамки темы данной статьи, поэтому интересующихся мы отсылаем к страницам онлайнового руководства по операционной системе, касающихся команд boot и loader (man 8 boot и man 8 loader).
Если все прошло успешно, то после перезагрузки вы будете работать в совершенно свежей операционной системе, только что собранной практически своими руками. С другой стороны, нельзя не напомнить о необходимости делать резервное копирование файловых систем перед началом апгрейда.
Ссылки:
- FreeBSD Handbook: http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/index.html
- Concurrent versions system: http://www.cvshome.org