dadv: (chuck)
[personal profile] dadv

Удаленная бинарная миграция FreeBSD с 8.2-RELEASE/i386 на 8.2-RELEASE/amd64 без доступа к консоли с двумя перезагрузками и минимальным downtime, безопасная настолько, насколько это возможно при обновлении "по месту". С некоторыми оговорками работает и для миграции c 8.2-STABLE.

Требуется доступность FreeBSD-8.2-RELEASE-amd64-livefs.iso (333MB). Быстрый и простой способ требует, чтобы на корневом разделе было свободно 64MB и дополнительно 401MB на разделе /var. Все команды выполняем от рута, используя шелл семейства sh/zsh/bash или подобный (на csh/tcsh не рассчитаны). В системе нужен пользователь (не root) группы wheel, шелл которого лежит в корневой файловой системе или в /usr.

  1. Скачать образ FreeBSD-8.2-RELEASE-amd64-livefs.iso.

  2. Установить xorriso из портов или пакетов для корректного раскрытия образа (штатные mdconfig и bsdtar не годятся: при раскрытии iso через mdconfig ломаются хардлинки, а bsdtar теряет атрибуты файлов).

  3. 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


  4. Занимаем 49MB в /boot:

    cp -rp livefs/boot/kernel /boot/kernel.GENERIC64

  5. Подготовка 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"

  6. Создаём свои образы, уменьшая размер:
    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

  7. Подгрузка полученного 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

  8. Перезагружаем систему, она загружается с /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.: автор не несет ответственности за выполнение указанной процедуры без полных и протестированных бекапов и без тренировки в лабораторных условиях. Неаккуратное выполнение команд из последнего пункта ПРИВЕДЕТ вашу систему в состояние, когда для её загрузки требуется восстановление с консоли.

This account has disabled anonymous posting.
(will be screened if not validated)
If you don't have an account you can create one now.
HTML doesn't work in the subject.
More info about formatting

If you are unable to use this captcha for any reason, please contact us by email at support@dreamwidth.org

Profile

dadv: (Default)
Choose your future

July 2024

M T W T F S S
12 34567
891011121314
15161718192021
22232425262728
293031    

Tags

Style Credit

Powered by Dreamwidth Studios