freebsd-update upgrade. custom kernel | FreeBSD

Бинарное обновление freebsd с ветки до ветки или в пределах одной ветки с одной стороны задача тривиальная. С другой стороны если у нас кастомное ядро – то проблемы могут возникнуть на ровном месте.

Прежде всего хендбук рекомендует проапгрейдить весь установленный софт, для того чтобы гарантировать что в процессе апгрейда библиотек и файлов у нас ничего не сломается. :) Это на самом деле важный момент поскольку после обновления ядра обновляются библиотеки которые может использовать установленный софт, и в результате обновления мы получим массу проблем с неработающим софтом – его нужно будет всё равно пересобирать.
__________________________
UPD: Здесь важный момент – в новой версии портов может не оказаться нужной вам версии софта (например старой версии php типа /usr/ports/php52 /usr/ports/php53 и т.д.) Так что с апгрейдом портов можно не спешить, или скопировать старое дерево куда-нибудь себе на диск. Если старый порт не собирается и возникли проблемы с софтом, посмотрите вариант решения в конце статьи.

#portsnap fetch
#portsnap update
#portupgrade -af

Если у нас ядро отличное от GENERIC то в процессе апгрейда мы получаем такое сообщение:

WARNING: This system is running a "MYKERNEL" kernel, which is not a
kernel configuration distributed as part of FreeBSD 6.3-RELEASE.
This kernel will not be updated: you MUST update the kernel manually
before running "/usr/sbin/freebsd-update install"

Самый простой вариант – собрать ядро GENERIC и установить. Это точно избавит нас от возможных проблем:

#cd /usr/src
#make -j8 buildkernel KERNCONF=GENERIC
#make installkernel KERNCONF=GENERIC

Если ядро generic у нас есть в каталоге /boot можем ничего не собирать а загрузить его:

Cмотрим как у нас называется ядро

#cd /boot
#ls | grep generic

Перезагружаемся, указав загрузить при загруке ядро generic:

#nextboot -k kernel.generic
#shutdown -r now

Проверяем какое ядро загрузилось:

# uname -a
FreeBSD somehost.ru 7.3-RELEASE-p1 FreeBSD 7.3-RELEASE-p1 #0: Wed May 26 04:29:05 UTC 2010 root@i386-builder.daemonology.net:/usr/obj/usr/src/sys/GENERIC i386

Всё ок. Теперь можно приступать к апгрейду.

Конечно можно апгрейдиться и с нестандартным ядром. Правда здесь возможностей получить проблемы больше.

Итак апгрейд в пределах ветки или до новой версии. Рекомендуют производить апгрейд поэтапно – проходя все стабильные релизы, проверяя что обновление прошло успешно. Например есть FreeBSD 6.0 Release, нужно дойти до восьмерки. Проходим все этапы – 6.0 – 6.2 -6.3 – 7.0 – 7.2 – 7.3 – 8.0
Если кто уверен в своих силах – может прыгать с ветки на ветку. :)

Далее все по хендбуку:

Копируем /etc и /boot/GENERIC (/boot/kernel.generic) на всяк случай куда удобно.
Обновляем порты и ставим portupgrade если не стоит (потом понадобится)

Если в /etc/make.conf что-то добавляли – то хендбук рекомендует всё оттуда убрать. (Ну мало ли оптимизировали под архитектуру и т.д.)

Начинаем:

freebsd-update -r 8.0-RELEASE upgrade

Пока никакого вмешателства в рабочую систему нет – все обновления наложение патчей идет в отдельной директории. Задаст пару вопросов относительно конфигов (на заметку – из редактора vi выходим комбинацией клавиш – «shift + :» и потом «q»). Листаем в конец списка файлов которые подвергаются изменениям – клавишей End.

Ставим.

#freebsd-update install

После этого перегружаемся. Поскольку патчится ядро – GENERIC его и грузим. (Обращаем внимание на то, чтобы в ядре GENERIC была поддержка всех железок – это на случай если вы настроили в своем ядре поддержку к примеру рейд контроллера):

#nextboot -k kernel.generic
#shutdown -r now

После перезагрузки ещё раз:

#freebsd-update install

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

Апдейтим руби
# portupgrade -f ruby

Удаляем старую базу портов

# rm /var/db/pkg/pkgdb.db
# portupgrade -f ruby18-bdb
# rm /var/db/pkg/pkgdb.db /usr/ports/INDEX-*.db

Апгрейдим всё что установлено.

# portupgrade -af

В принципе сначала можно завершить обновление, загрузить ядро generic, и посмотреть обновилось ли оно, а после этого заняться приложениями. Поскольку если портапгрейд не обновит гладко весь софт (а он скорее всего не обновит если мы не проапгрейдили всё ещё до обновления), то в процессе ручного управления есть вероятность того что после наших манипуляций мы получим отсутствие необходимых библиотек после финального freebsd-update install.

Делаем последний раз (удаляются старые библиотеки):

#freebsd-update install

Обращаем внимание что в процессе апгрейда не стоит делать никаких дополнительных манипуляций – типа freebsd-update fetch,install и т.д. (ну вдруг по истории команд пройдетесь и перепутаете). :)

После этого смотрим что у нас с софтом, апгрейдим его, если есть с чем-то проблемы – можно поставить порт совместимости с предыдущей веткой (например compat6x) или посмотреть ести ли в конфиге ядра опция совместимости с предыдущей веткой.

После этого снова собираем кастомное ядро.

Для ветки 6.0 вроде как бинарное обновление производится с помощью скриптов:

#fetch http://people.freebsd.org/~cperciva/freebsd-update-upgrade.tgz
#tar -xf freebsd-update-upgrade.tgz
#sh freebsd-update.sh -f freebsd-update.conf -r 6.3-RELEASE upgrade
#sh freebsd-update.sh -f freebsd-update.conf install
#shutdown -r now
#sh freebsd-update.sh -f freebsd-update.conf install
#shutdown -r now

Если ядро – не generic – то перед каждой перезагрузкой указываем грузить generic.

PS: Статья – по сути черновик. Вполне вероятны ошибки и неточности. Если заметили что где-то сказал глупость – поправьте. Что-то в процессе если сам замечу – исправлю. :)
PPS: Cсылка на статью из хендбука http://www.freebsd.org/doc/handbook/updating-upgrading-freebsdupdate.html

____________________________________________

Update.
Аккуратнее с бинарным обновлением с ветки на ветку с сильными изменениями. например с 7 до 8 и командами типа make delete-old и т.д. Перед последним freebsd-update install стит позаботиться о софте.
Если софт не переустанавливали то можем получить ошибки на отсутствие бибилотек. Здесь поможет порт /usr/ports/misc/compat7x (и по аналогии 6x, 8x и тд)
Но чтобы его поставить можем поймать ругань на отсутствующие библиотеки tar

/libexec/ld-elf.so.1: Shared object "libcrypto.so.5" not found, required by "tar"

Смотрим какие библиотеки не может найти:

ldd /usr/bin/tar

Переходим в директорию cd /usr/lib/ и сделаем симлинк:

#cd /usr/lib/
#ls | grep libcrypto.so
#libcrypto.so
#ln -s libcrypto.so libcrypto.so.5

Так по всем остальным библиотекам необходимым для tar. Собираем и ставим порт compat7x
Весь софт должен заработать, порты собираться.
Если дерево портов старое – обычное дело отсутствующие файлы дистрибутивов. Ищем гуглом и кладем в дистфайлз

#cd /usr/ports/distfiles
#fetch http://путь к файлу в сети

Снова собираем порт. Всё должно работать
_________________________________________________

Update

Ещё один хинт по поводу установленного ПО: в случае если может понадобиться старая версия php, mysql и т.д. можно попытаться сохранить каталог /usr/ports и пробовать собрать пакеты с помощью bmake
Перед установкой апдейтов – поставьте /usr/ports/devel/bmake
Пользоваться как и обычным make

bmake config
bmake
bmake install

Он поможет собрать старые порты когда make в новой версии оси начнет ругаться
Unknown modifier 't'
или

make "/usr/ports/Mk/bsd.port.mk" line 5021: warning: duplicate script for target "-depends" ignored
make: "/usr/ports/Mk/bsd.port.mk" line 5021: warning: using previous script for "-depends" defined here

Конечно старые версии файлов уже убраны из основных репозитариев. Берем на вооружение сайты вроде http://www.filewatcher.com/ и качаем нужные файлы в /usr/ports/distfiles вручную.
У меня так получилось завести php52 и php52-extensions на FreeBSD 9.0.