Home

Удалённо обновляем FreeBSD 7.4-STABLE до 8.4-STABLE

Предисловие.

Есть мнение, что для успешного обновления одной ветки до другой нужно сначала обновить установленную версию до самое свежей версии в этой ветки. Поэтому сначала я обновился 7.4 до STABLE через csup. Здесь про это не буду писать. К тому же, эта система уже была обновлена до состояния на 2013-03-02, поэтому я не стал её обновлять до текущей даты (2013-03-31).

Теперь на обновлённой до 7.4-STABLE системе делаем следующее:

# rm -r /usr/obj/

# rm -r /usr/src/

Далее установил subversion.

# cd /usr/src/devel/subversion/

# make install clean

# svn co svn://svn.freebsd.org/base/stable/8 /usr/src

Так как я планирую сразу после обновления системы обновлять порты, то нужно обновить дерево портов сейчас - потом оно может не заработать из-за смены версии FreeBSD

# rm -r /usr/ports/

# svn co svn://svn.FreeBSD.org/ports/head /usr/ports

 

Дальше удалённо пересобираем систему FreeBSD.

# cd /usr/src/

# mergemaster -p

# make -j4 buildworld

# make -j4 buildkernel

# make installkernel

# make installworld

 

команда mergemaster -iU не выполняется. Ругается что не может чего-то там сделать cd /usr/src

 

# reboot

 

загрузилось

 

# uname -a

FreeBSD web2.yaol.ru 8.4-PRERELEASE FreeBSD 8.4-PRERELEASE #0 r248935: Sun Mar 31 05:00:20 MSK 2013     Этот адрес электронной почты защищен от спам-ботов. У вас должен быть включен JavaScript для просмотра.:/usr/obj/usr/src/sys/KMD  amd64

 

возвращаемся к тому, на чём прервались

# mergemaster -iU

теперь оно успешно выполнилось. На все вопросы по удалению и выполнению я отвечал y.

 

# reboot

 

дальше нужно пересобирать все порты в принудительном порядке.

я делаю это так:

# portupgrade -farR

 

Однако, в моих планах сделать upgrade сразу до 9.1-STABLE

 ЗЫ Для проверки запустил portupgrade -an и он скачал INDEX-8.bz2, то есть работает.

FreeBSD 9.1: RAID1 - Mirroring

 

Предисловие.

Мдя. Рабочей инструкции по запросу как поставить/замиррорить систему FreeBSD 9.1 на RAID1 с помощью gmirror я так и не нашёл.

Русский FreeBSD handbook отсюда http://www.freebsd.org/doc/ru/books/handbook/geom-mirror.html устарел, даже нумерация статьи 19.4 не соответствует официальной английской, которая уже стала 20.4 http://www.freebsd.org/doc/handbook/geom-mirror.html

Вот эта инструкция не работает на 9.1 http://www.opennet.ru/tips/info/2681.shtml - на некоторые команды система ругается. Адаптировать не удалось. В какой-то момент установка началась на gm0 раздел, но при попытке установить рутовый пароль (когда инсталлер FreeBSD вываливается в коммандную строку) процесс каким-то странным образом замерзал.

Эта инструкция http://www.ateamsystems.com/blog/Installing-FreeBSD-9-gmirror-GPT-partitions-raid-1 меня не порадовала - как-то сильно далека она от официального handbook'а.

Итого. Вернёмся к официальному FreeBSD handbook'у http://www.freebsd.org/doc/handbook/geom-mirror.html

 

Процесс - FreeBSD gmirror raid1.

Ставим FreeBSD 9.1, как мы это обычно делаем. Без всяких заморочек. Перегружаемся в свежеустановленную систему. Все дальшеописанные команды я делал через ssh-подключение.

Если до этого оставались какие-то хвосты от предыдущих попыток запустить gmirror, то делаем gpart destroy -F ada1 - на ada0 оно было всё стёрто в процессе установки.

Далее следуем инструкциям из FreeBSD HandBook 20.4.3

# gmirror load

# diskinfo -v ada0 |head -n3
ada0
        512             # sectorsize
        1000204886016   # mediasize in bytes (931G)

# diskinfo -v ada1 | head -n3
ada1
        512             # sectorsize
        1000204886016   # mediasize in bytes (931G)

# geom zero load

# gnop create -s 1000204886016 gzero
Это число взято из предыдущей команды.

# gmirror label -v gm0 gzero.nop ada1
Metadata value stored on gzero.nop.
Metadata value stored on ada1.
Done.

# gmirror forget gm0

А вот дальше начинается интересное - я решил посмотреть, что показывает команда gpart show из инструкции (заглянул так сказать вперёд) и оказалось вот что:

# gpart show ada0
=>        34  1953525101  ada0  GPT  (931G)
          34           6        - free -  (3.0k)
          40         128     1  freebsd-boot  (64k)
         168  1944059768     2  freebsd-ufs  (927G)
  1944059936     8388608     3  freebsd-swap  (4.0G)
  1952448544     1076591        - free -  (525M)

# gpart backup ada0
GPT 128
1   freebsd-boot         40        128
2    freebsd-ufs        168 1944059768
3   freebsd-swap 1944059936    8388608

А в handbook'е пишут про MBR 4 и BSD 8 - а это, как я понимаю, уже прошлый век.

И! У меня в конце оказалось 525 свободных мегабайт. Видимо потому что инсталлятор по умолчанию оперирует гигабайтам. Поэтому следующий шаг из официального handbook'а FreeBSD я пропускаю. В нём размер последнего слайса/партиции/etc уменьшается на 1 сектор, в результате чего команда gpart show начинает показывать - free -  (31k) в последней строке. У меня там итак уже 525M свободно.

# gpart backup ada0 > table.ada0
Если же у тебя нет свободного места в конце диска, то нужно последнее число в последней строке уменьшить на 1 (на единицу).

На моём примере должно было бы получиться
3   freebsd-swap 1944059936    8388607

# gpart restore mirror/gm0 < table.ada0

# gpart show mirror/gm0
=>        34  1953525100  mirror/gm0  GPT  (931G)
          34           6              - free -  (3.0k)
          40         128           1  freebsd-boot  (64k)
         168  1944059768           2  freebsd-ufs  (927G)
  1944059936     8388608           3  freebsd-swap  (4.0G)
  1952448544     1076590              - free -  (525M)

# newfs -U /dev/mirror/gm0p2
/dev/mirror/gm0p2: 949247.9MB (1944059768 sectors) block size 32768, fragment size 4096
        using 1517 cylinder groups of 626.09MB, 20035 blks, 80256 inodes.
        with soft updates
super-block backups (for fsck_ffs -b #) at:
 192, 1282432, 2564672, 3846912, 5129152, 6411392, 7693632, 8975872, 10258112, 11540352, 12822592,
....

# gpart bootcode -b /boot/pmbr mirror/gm0
bootcode written to mirror/gm0

# gpart set -a active -i 1 mirror/gm0
gpart: attrib 'active': Invalid argument

лезем в man gpart и выясняем, что нужно делать так:

# gpart set -a bootme -i 1 mirror/gm0
bootme set on mirror/gm0p1

команде gpart bootcode -b /boot/boot mirror/gm0s1 я не нашёл аналога - по идее это должно было бы быть gpart bootcode -b /boot/gptboot mirror/gm0p1 но нет.

(UPD после того, как система сдублировалась и была перезагружена, оказалось, что она не грузится. Видимо затёрся бутсектор или ещё какая-то фигня стряслась. После вкуривания интернетов и манов команда gpart bootcode -b /boot/mbr mirror/gm0 была пофикшена в gpart bootcode -b /boot/pmbr mirror/gm0 и выполнена после загрузки с установочного диска. Команда gpart bootcode -b /boot/gptboot mirror/gm0p1 всё равно ни разу не выполнялась без ошибок. То есть я так и не понял, какая команда записывает нужные данные на раздел freebsd-boot)

далее лезем в /etc/fstab, чтобы заменить /dev/ada0* на /dev/mirror/gm0*

Handbook рекомендует сделать копию

# cp /etc/fstab /etc/fstab.orig

# vi /etc/fstab
# Device        Mountpoint      FStype  Options Dump    Pass#
/dev/mirror/gm0p2       /               ufs     rw      1       1
/dev/mirror/gm0p3       none            swap    sw      0       0

Далее в файл vi /boot/loader.conf добавляем строку geom_mirror_load="YES"

Теперь пришло время скопировать систему с /dev/ada0p2 на /dev/mirror/gm0p2

# mount /dev/mirror/gm0p2 /mnt

# mount
/dev/ada0p2 on / (ufs, local, journaled soft-updates)
devfs on /dev (devfs, local, multilabel)
/dev/mirror/gm0p2 on /mnt (ufs, local, soft-updates)

 Дальше забиваем временно на FreeBSD Handbook и клонируем раздел с помощью команды pax

# cd /

# pax -p eme -X -rw . /mnt
pax: /mnt/./var/run/devd.pipe skipped. Sockets cannot be copied or extracted
pax: /mnt/./var/run/log skipped. Sockets cannot be copied or extracted
pax: /mnt/./var/run/logpriv skipped. Sockets cannot be copied or extracted

Скопировалось буквально за минуту.

# df -h
Filesystem           Size    Used   Avail Capacity  Mounted on
/dev/ada0p2          897G    703M    825G     0%    /
devfs                1.0k    1.0k      0B   100%    /dev
/dev/mirror/gm0p2    897G    703M    825G     0%    /mnt

 Теперь перегружаемся. Если всё пойдёт, как должно быть, то мы загрузимся с mirror/gm0

# reboot

 Загрузилось.

# mount
/dev/mirror/gm0p2 on / (ufs, local, soft-updates)
devfs on /dev (devfs, local, multilabel)

Журналирование куда-то делось. Непонятно, должно ли оно было там быть на gmirror разделах - не знаю.

ВНИМАНИЕ! Теперь, мы в миррор будем подключать наш изначальный диск ada0 - все данные при этом на нём сотрутся.

На данный момент статус таков:

# gmirror status
      Name    Status  Components
mirror/gm0  COMPLETE  ada1 (ACTIVE)

# gmirror insert gm0 ada0
В ответ не было сказано ни слова, хотя в handbook'е написан некий вывод GEOM_MIRROR: Device gm0: rebuilding provider ada0.

# gmirror status
      Name    Status  Components
mirror/gm0  DEGRADED  ada1 (ACTIVE)
                      ada0 (SYNCHRONIZING, 0%)

Синхронизирует оно всё это очень вяло как-то. При этом нагрузки на проц нету никакой.

А вот и ответ.

Оно, видимо, клонирует всю поверхность диска без разбора.

# gstat
dT: 1.002s  w: 1.000s
 L(q)  ops/s    r/s   kBps   ms/r    w/s   kBps   ms/w   %busy Name
    0      0      0      0    0.0      0      0    0.0    0.0| cd0
    0      0      0      0    0.0      0      0    0.0    0.0| iso9660/FREEBSD_INSTALL
    2   1277      0      0    0.0   1277 161984    1.0   83.0| ada0
    0   1266   1266 162106    0.5      0      0    0.0   54.0| ada1
    1   1266   1266 162106    0.6      0      0    0.0   56.1| mirror/gm0
    0      0      0      0    0.0      0      0    0.0    0.0| mirror/gm0p1
    0      0      0      0    0.0      0      0    0.0    0.0| mirror/gm0p2
    0      0      0      0    0.0      0      0    0.0    0.0| mirror/gm0p3 

Насколько мы помним - у меня там было занято 703M из 897G.

Вот и всё. Теперь можно обновлять систему до STABLE и ставить порты через систему SVN.

Обновляем FreeBSD удалённо

Преамбула.

В хэндбуке FreeBSD написано, что нужно делать перезагрузку в single mode в процессе обновления системы. На рабочих серверах это архисложно, особенно если их десятки и через них гоняется трафик сотнями мегабит в секунду.

Поэтому я уже много лет обновляю FreeBSD удалённо через SSH пока без каких-либо проблем. Кроме единственного случая в стародавние времена на ветке 7.X, но я чего-то там походу напортачил в процессе, поэтому пришлось ехать к машине и пользоваться директорией /rescue при этом вкуривая интернет с соседней машины. Была весёлая ночь.

До пересборки системы FreeBSD я обновил её исходники через SVN репозиторий (subversion). Читай мой предыдущий пост. Теперь могу приступить к пересборке текущей STABLE версии из исходников. Бинарные обновления не делаю, потому что они создаются (насколько я знаю) без оптимизации под архитектуру. У меня это athlon64.

Обновлять FreeBSD будем из исходников, поэтому как минимум нужно обновить исходники FreeBSD.

Обновляем FreeBSD удалённо.

# cd /usr/src/

# mergemaster -p

В хэндбуке написано, что это надо делать где-то в середине процесса, да ещё и в single mode. Я делаю это в самом начале и позже ты поймёшь почему.

Обновляем файлы с крайней осторожностью! Обычно оно обновляет два файла - список юзеров (/etc/passwd) и список групп (/etc/group). Если обновишь так, что удалится твой юзер, то на машину после ребута ты уже не попадёшь. Нужно будет ехать к ней и менять пароли через single mode.

# make -j8 buildworld

-j4 я делаю на 4х процессорной машине, на 8ми процессорной делаю -j8. Хотя говорят можно делать и по 4 процесса на ядро. На какой-то мощной машине я делал -j16 - мир пересобирался минут за 20. Но мне спешить некуда, поэтому обычно я делаю -j8.

# make -j8 buildkernel

так собрал ядро. Искал тут инфу как можно обновить FreeBSD 7.X до 9.X - вместо этого наткнулся на статью на хабре, где сначала собирают ядро (buildkernel), а потом world (buildworld). Не знаю, мир перевернулся что ли?! В русской версии хэндбука по-прежнему написано, что сначала buildworld, потом buildkernel - не вижу причин противоречить handbook'у в данном случае.

Устанавливаем ядро.

# make installkernel

Где-то теперь по FreeBSD handbook полагается shutdown now и так далее. Но на удалённой машине этого не сделаешь, поэтому дальше устанавливаем мир.

# make installworld

теперь нужно запустить mergemaster для обновления разных скриптов и конфигов. Нажимать y на необновлённых файлах меня не радует, поэтому запускаем с параметром -iU.

# mergemaster -iU

Возможно будет спрашивать про обновление разных файлов. Обновляем с осторожностью - система-то удалённая, а ехать к ней не хочется. При обновлении первой строки с номером версии файла выбирай правый вариант, то есть обновлённый. А дальше выбирай левый вариант, если тебе нужно сохранить твои изменения. Точно также надо было действовать в начале при выполнении команды mergemaster -p. Если в начале ты не обновил верхнюю строку, то ты ещё можешь это сделать, чтобы при следующем обновлении системы оно не задавало вопросы про эти файла, если там не появлялось никаких изменений.

В конце оно будет спрашивать запустить ли rebuild разных файлов типа newaliases - я отвечаю y - по умолчанию там выбрано n.

Ну и теперь перезагружаем систему.

# reboot

Через минуту-две машина возвращается онлайн и мы продолжаем с ней работать, если нужно или же у неё поднимаются все сервисы и она продолжает работать в штатном режиме.

 

Всё тоже самое можно делать в три строки. И это очень удобно, потому что запустил процесс и забыл про сервер на пару часов, а не сидишь и мониторишь его, когда он там пришёл к следующему шагу. И это как раз та причина, почему я mergemaster -p делаю в самом начале.

# mergemaster -p
# make -j8 buildworld && make -j8 buildkernel && make installkernel && make installworld && mergemaster -iU
# reboot

Обращаю внимание, что нужно пользовать именно два амперсанда - && - если в каком-то шаге произойдёт ошибка, то следующая команда выполняться не будет. И тогда уже будешь делать всё пошагово и смотреть в чём проблема.

 

PS

Вот и мои два FreeBSD сервера поднялись и при логине на них они теперь указывают, по всей видимости, версию SVN-исходников, на основании которых собрана FreeBSD. Выглядит это так:

FreeBSD 9.1-PRERELEASE (KMD) #0 r243371M: Wed Nov 21 18:15:48 MSK 2012

У тебя скорее всего вместо KMD будет написано GENERIC. То есть ядро по умолчанию. Я собираю обычно кастомное ядро, даже если в нём нет никаких изменений. Просто мне так удобнее понимать, что система пересобрана с моими настройками, например, с оптимизацией под процессор athlon64. При этом у меня:

В /etc/make.conf добавлены строки:

CPUTYPE?=athlon64
KERNCONF=KMD

?= означает, что нужно собирать систему без жёсткой привязки к архитектуре, насколько я понимаю, то есть собранная так система запускалась у меня как-то на athlon-xp без особых проблем.

Файл KMD выглядит так:

include         GENERIC
ident           KMD

А в директории
/usr/src/sys/amd64/conf
у меня сделан symlink на файл KMD (не забудь находиться в указанной выше директории), который лежит в моей домашней директории.
ln -s /usr/home/<user>/KMD

 

PS2

Иногда для чистоты сборки системы, особенно при апгрейде с одной версии на другую нужно зачищать директорию /usr/obj/

# rm -r /usr/obj/

Если оно на что-то ругнулось и/или директория не удалилась, то выполняем следующую команду, а потом повторяем предыдущую.

# chflags -R noschg /usr/obj/

 

PS3

Для чистоты обновления системы залез в английский FreeBSD handbook выяснить относительно текущего состояния make delete-olds.

Делаем:

# cd /usr/src
# make check-old

Если выдаёт что-то отличное от:

root@www9:/usr/src # make check-old
>>> Checking for old files
>>> Checking for old libraries
>>> Checking for old directories
To remove old files and directories run 'make delete-old'.
To remove old libraries run 'make delete-old-libs'.

Например, у меня выдало:

root@www9:/usr/src # make check-old
>>> Checking for old files
/usr/include/clang/3.1/unwind.h
/etc/auth.conf
/usr/share/examples/etc/auth.conf
/usr/share/man/man3/auth.3.gz
/usr/share/man/man5/auth.conf.5.gz
/usr/include/clang/3.0/altivec.h
/usr/include/clang/3.0/avxintrin.h
/usr/include/clang/3.0/emmintrin.h
/usr/include/clang/3.0/immintrin.h
/usr/include/clang/3.0/mm3dnow.h
/usr/include/clang/3.0/mm_malloc.h
/usr/include/clang/3.0/mmintrin.h
/usr/include/clang/3.0/nmmintrin.h
/usr/include/clang/3.0/pmmintrin.h
/usr/include/clang/3.0/smmintrin.h
/usr/include/clang/3.0/tmmintrin.h
/usr/include/clang/3.0/wmmintrin.h
/usr/include/clang/3.0/x86intrin.h
/usr/include/clang/3.0/xmmintrin.h
/usr/share/man/man9/net_add_domain.9.gz
>>> Checking for old libraries
>>> Checking for old directories
/usr/include/clang/3.0
/usr/include/c++/v1/ext
/usr/include/c++/v1
To remove old files and directories run 'make delete-old'.
To remove old libraries run 'make delete-old-libs'.

Поэтому я выполнил:

# make delete-old

Однако, чтобы не подтверждать удаление каждого файла вручную, делаем так:

# yes|make delete-old

На выходе будет что-то типа этого:

root@www9:/usr/src # yes | make delete-old
>>> Removing old files (only deletes safe to delete libs)
remove /usr/include/clang/3.1/unwind.h? remove /etc/auth.conf? remove /usr/share/examples/etc/auth.conf? remove /usr/share/man/man3/auth.3.gz? remove /usr/share/man/man5/auth.conf.5.gz? remove /usr/include/clang/3.0/altivec.h? remove /usr/include/clang/3.0/avxintrin.h? remove /usr/include/clang/3.0/emmintrin.h? remove /usr/include/clang/3.0/immintrin.h? remove /usr/include/clang/3.0/mm3dnow.h? remove /usr/include/clang/3.0/mm_malloc.h? remove /usr/include/clang/3.0/mmintrin.h? remove /usr/include/clang/3.0/nmmintrin.h? remove /usr/include/clang/3.0/pmmintrin.h? remove /usr/include/clang/3.0/smmintrin.h? remove /usr/include/clang/3.0/tmmintrin.h? remove /usr/include/clang/3.0/wmmintrin.h? remove /usr/include/clang/3.0/x86intrin.h? remove /usr/include/clang/3.0/xmmintrin.h? remove /usr/share/man/man9/net_add_domain.9.gz?
>>> Old files removed
>>> Removing old directories
/usr/include/clang/3.0
/usr/include/c++/v1/ext
/usr/include/c++/v1
>>> Old directories removed
To remove old libraries run 'make delete-old-libs'.

 

Так как old libraries не были замечены, то их удалять и не стал, ибо нечего.

переход с cvsup на subversion

Внезапно обнаружил для себя при обновлении src-дерева файл со странным названием LASTCOMMIT.txt

Пошёл рыть в интернет и внезапно обнаружил, что cvsup is depricated, то есть всё - капут. От этой системы принято решение окончательно отказаться в кратчайшие сроки. Правда, насколько я вкурил в интернеты, cvsup будет поддерживаться пока поддерживаются версии 9.0-RELEASE, 8.3-RELEASE, 7.4-RELEASE. Однако, до этого я обновлялся через csup и оно обновилось до 9.1-PRERELEASE.

Благо уже несколько лет исходники системы ведутся в subversion. А в cvsup оно лишь транслировалось. С другой стороны через cvsup были и коммиты (внесение изменений), теперь, насколько я понимаю, csup будет работать в режиме только для чтения.

Да тут ещё и инцидент с компрометацией двух серверов из кластера FreeBSD. Правда ответственные люди заявляют, что это были сервера сторонних приложений и основные сервера с src, ports и doc деревьями затронуты не были. Но, насколько я понял их ломаный английский, они не уверены.

Одним словом нужно пользовать subversion. Как организовать свой subversion mirror я пока не разбирался, и случайно на эту инфу не натыкался, сдаётся мне что оно ещё отсутствует в природе: "The FreeBSD svn mirror network is still in its early days, and will likely change." Mirror SVN