Удаленная бинарная миграция FreeBSD с 8.2-RELEASE/i386 на 8.2-RELEASE/amd64 без доступа к консоли с двумя перезагрузками и минимальным downtime, безопасная настолько, насколько это возможно при обновлении "по месту". С некоторыми оговорками работает и для миграции c 8.2-STABLE.
Требуется доступность
- Скачать образ FreeBSD-8.2-RELEASE-amd64-livefs.iso.
- Установить xorriso из портов или пакетов для корректного раскрытия образа (штатные mdconfig и bsdtar не годятся: при раскрытии iso через mdconfig ломаются хардлинки, а bsdtar теряет атрибуты файлов).
- TMPDIR устанавливаем в какой-нибудь каталог раздела /var.
Разворачиваем образ, игнорируя ошибки касательно boot.catalog:TMPDIR=/var/tmp/work
mkdir -p $TMPDIR
cd $TMPDIR
rm -rf livefs
xorriso -for_backup -load volid \* -indev /path/to/FreeBSD-8.2-RELEASE-amd64-livefs.iso -osirrox on -- -extract / livefs -rollback_end - Занимаем 49MB в /boot:
cp -rp livefs/boot/kernel /boot/kernel.GENERIC64 - Подготовка mfsroot.
Копируем минимально необходимый набор файлов для успешного удаленного входа:cd /etc
cp -rp fstab hostid host.conf nsswitch.conf rc.conf ssh resolv.conf passwd group master.passwd pwd.db spwd.db $TMPDIR/livefs/etc
Стоит убедиться, что в $TMPDIR/livefs/etc/resolv.conf указан обслуживающий нас DNS-сервер, а не 127.0.0.1 лишь только и при необходимости отредактировать этот файл.
Теперь нужно привести$TMPDIR/livefs/etc/fstabк примерно следующему виду:# Device Mountpoint FStype Options Dump Pass# /dev/md0.uzip / ufs ro 0 0 /dev/md1.uzip /usr ufs ro 0 0 /dev/ad0s1b none swap sw 0 0 /dev/ad0s1a /mnt ufs rw 2 0 /dev/ad0s1e /mnt/var ufs rw 2 0 /dev/ad0s1d /mnt/usr ufs rw 2 2
Первые две строки обязательно такие, остальные - из оригинального fstab, точку монтирования для рута заменяем на /mnt, /usr и /var тоже смещаем внутрь /mnt, остальные файловые системы (если есть) намеренно не упоминаем. Колонки Dump и Pass заполняем указанными значениями.
Создаём файлrc.initdiskless:cd $TMPDIR/livefs/etc touch diskless cat > rc.initdiskless <<EOF #!/bin/sh cd / for fs in /mnt /mnt/var do if fsck -p \$fs || fsck -y \$fs; then mount \$fs else exit 1 fi done mdconfig -af $TMPDIR/usr.uzip -u1 mount /usr mdconfig -at malloc -s 5M -u2 newfs /dev/md2 mount -o async /dev/md2 /etc tar -xpzf $TMPDIR/etc.tgz EOFВ
$TMPDIR/livefs/etc/rc.confжелательно отключить все сервисы, кроме
sshd и каналообразующих (учитывать, что грузиться будет GENERIC), что-то типа этого:root_rw_mount="NO" # эта строка обязательна hostname="host.domain.ru" defaultrouter="x.x.x.x" ifconfig_em0="inet x.x.x.y/24" sendmail_enable="NONE" firewall_enable="NO" inetd_enable="NO" sshd_enable="YES" fsck_y_enable="YES" background_fsck="NO"
- Создаём свои образы, уменьшая размер:
alias mkfs='makefs -t ffs -o bsize=4096 -o fsize=512 -o minfree=3 -o optimization=space' cd $TMPDIR/livefs rm -rf boot tmp var usr/games usr/include usr/share ln -s /mnt/var . ln -s /mnt/tmp . ln -s /mnt/boot . ln -s /mnt/home . ( cd usr; ln -s /mnt/usr/include .; ln -s /mnt/usr/share . chmod u+s bin/su mkfs $TMPDIR/usr . ) rm -r usr; mkdir usr mkuzip ../usr; rm ../usr tar czf ../etc.tgz etc find -d etc \! -name etc -a \! -name rc -a \! -name fstab -a \! -name diskless\ -a \! -name rc.initdiskless -a \! -name login.conf.db -a \! -name group -delete mkfs ../mfsroot . cd .. rm -r livefs mkuzip mfsroot; rm mfsroot cp -rp /etc . echo 'ldconfig32_paths="$ldconfig32_paths /lib /usr/lib /usr/local/lib /usr/local/lib/compat/pkg"' >> etc/rc.conf
- Подгрузка полученного mfsroot, занимаем ещё 8.2MB в /boot:
cd /boot mv $TMPDIR/mfsroot.uzip . cat <<EOF > nextboot.conf nextboot_enable="YES" kernel="kernel.GENERIC64" geom_uzip_load="YES" mfsroot_load="YES" mfsroot_type="mfs_root" mfsroot_name="/boot/mfsroot.uzip" vfs.root.mountfrom="ufs:/dev/md0.uzip" vfs.root.mountfrom.options="ro" EOF
- Перезагружаем систему, она загружается с /boot/kernel/kernel.GENERIC64 и монтирует в качестве корня изготовленный mfsroot.uzip с бинарниками архитектуры amd64, запускает sshd. Входим нашим пользователем (см. выше), при помощи su поднимаем привилегии. Теперь можно обновиться (файловые системы смонтированы в /mnt) любым удобным способом. Это - точка невозврата, сейчас ещё можно перезагрузить систему и она вернется в исходное состояние. Дальше уже нет, возврат только через восстановление из бекапов с консоли.
Я обновлял через sysinstall по сети:find /mnt -maxdepth 3 -flags +schg -exec chflags noschg {} +
sysinstall
В меню Options сменить Install Root на /mnt.
Выбрать режим Upgrade, в меню Choose Distributions выбрать Custom и там пометить только base и lib32 (ядро уже установлено). Установка с FTP проходит совершенно гладко. После окончания установки выходим из sysinstall. Далее:echo 'kernel="kernel.GENERIC64"' >> /mnt/boot/loader.conf mv /mnt/etc /mnt/etc.0 cp -rp /mnt/var/tmp/work/etc /mnt # тут используем путь вида /mnt/$TMPDIR/etc.
Снова перезагружаемся, теперь система грузится уже не с образа mfsroot, а штатно.
После перезагрузки можно удалить /boot/mfsroot.uzip и $TMPDIR. Базовая система обновлена и должна работать штатно. Если производилась миграция со STABLE, самое время выполнить стандартный source upgrade.
Что касается установленного стороннего софта, тут возможны варианты:
- Не будут работать сторонние модули ядра до их обновления на версии amd64. Для модулей ядра важно, чтобы в /usr/src/sys на момент сборки лежали в точности те же исходники, из которых собрано ядро, с которым будет запускаться модуль. Например, если в /usr/src/sys лежат исходники от 8.2-STABLE, то собранный с ними сторонний ядерный модуль может не заработать с ядром от 8.2-RELEASE.
- Подавляющее большинство прикладного софта будет работать как ни в чём не бывало при условии прописывания в
/etc/rc.confстрокиldconfig32_paths(см. выше) со всеми путями, где лежат нужные программам разделяемые библиотеки.
Например, после выполнения этой миграции для моего десктопа и подмены nvidia.ko на версию amd64 (не переустановки драйвера из портов целиком!) у меня заработали установленные ранее xorg-7.4_2, xfce4, OpenOffice, игры с использованием 3D-ускорения NeverBall и Quake3 OpenArena после приведения ldconfig32_paths к такому виду:ldconfig32_paths="$ldconfig32_paths /lib /usr/lib /usr/local/lib /usr/local/lib/compat/pkg /usr/local/lib/event2 /usr/local/lib/gcc44 /usr/local/lib/xorg/modules/extensions /usr/local/lib/gegl-0.1 /usr/local/lib/graphviz /usr/local/lib/libxul /usr/local/lib/nss /usr/local/lib/qt4 /usr/local/lib/virtualbox /usr/local/lib/zsh /usr/local/lib/firefox /usr/local/openoffice.org-OOO310_m18/openoffice.org/ure/lib /usr/local/openoffice.org-OOO310_m18/openoffice.org/basis3.1/program"
Команда ldconfig -32 -m dir позволяет добавлять новые каталоги без перезагрузки.
Не заработал firefox4: до убирания ~/.mozilla при старте FF сразу делал exit(1), а после убирания стал сразу падать с SIGSEGV.
Поэтому, следующим шагом может быть удаление всех пакетов и переустановка их версий для amd64 - пакетами или просто пересборкой из портов.
N.B.: автор не несет ответственности за выполнение указанной процедуры без полных и протестированных бекапов и без тренировки в лабораторных условиях. Неаккуратное выполнение команд из последнего пункта ПРИВЕДЕТ вашу систему в состояние, когда для её загрузки требуется восстановление с консоли.