21.6. Пересборка мира
Пред. | Глава 21. Обновление системы и смена версии FreeBSD | След.

## 21.6. Пересборка мира

После того, как локальное дерево исходных текстов было синхронизировано с некоторой версией FreeBSD (FreeBSD-STABLE или FreeBSD-CURRENT), его можно использовать для перестроения системы. Этот процесс известен как перестроение мира.

Перед перестроением мира убедитесь в выполнении следующих действий:

Процедура 21.1. Перед тем как приступать к построению мира

1. Сохраните резервную копию всех важных данных на другую систему или съёмный носитель, проверьте её целостность и держите под рукой загрузочный носитель. Невозможно переоценить важность создания резервной копии системы до начала перестроения системы. Хотя перестроение системы является простой задачей, неизбежно возникают ситуации, при которых ошибки в исходных текстах приводят к тому, что система перестаёт загружаться. Возможно, вам никогда не придётся этим воспользоваться, но, постучав по дереву, всегда лучше подстраховаться.

2. Проверьте последние сообщения в списке рассылки freebsd-stable или freebsd-current (в зависимости от отслеживаемой ветки). Будьте в курсе любых известных проблем, и тех систем, которые они затрагивают. В случае возникновения подобной проблемы, дождитесь сообщения о том, что эта проблема решена. После этого повторите синхронизацию исходных текстов для получения необходимого исправления.

3. Прочтите `/usr/src/UPDATING` для получения информации о дополнительных шагах, необходимых для данной версии исходных текстов. В этом файле содержится важная информация о возможных проблемах и может быть указан порядок выполнения соответствующих команд. При большинстве обновлений требуются дополнительные шаги, например, переименование или удаление определённых файлов перед установкой нового мира. Эти шаги будут перечислены в конце файла, где в явном виде описывается текущая рекомендуемая последовательность действий при обновлении. Если содержимое `UPDATING` противоречит каким-либо шагам в этой главе, руководствуйтесь инструкциями в файле `UPDATING`, которые имеют больший приоритет.

### Не используйте `make world`:

В некоторой устаревшей документации рекомендуется использование `make world`. Эта команда пропускает некоторые важные шаги, поэтому использовать её следует лишь в том случае, если вы точно знаете, что делаете. Почти во всех случаях `make world` - это неправильный способ, вместо этого следует использовать описанную здесь процедуру.

### 21.6.1. Обзор процесса

Процесс построения мира подразумевает переход с более старой версии FreeBSD с использованием исходных текстов более новой версии, которые были получены согласно инструкциям в Раздел 21.5, <<Синхронизация исходных текстов>>.

Во FreeBSD термин <<world>> обозначает ядро, исполняемые файлы основой системы, библиотеки, файлы для программирования и встроенный компилятор. Имеет значение порядок, при котором эти компоненты собираются и устанавливаются.

Например, из-за ошибки в старом компиляторе невозможно было бы скомпилировать новое ядре. Поскольку новое ядро должно быть собрано новым компилятором, для этого в свою очередь необходимо собрать новый компилятор, но устанавливать его перед сборкой ядра необязательно.

Новый мир может зависеть от особенностей нового ядра, поэтому новое ядро должно быть установлено до установки нового мира. Старый мир может работать неправильно на новом ядре, поэтому новый мир должен быть установлен сразу после установки нового ядра.

Перед установкой нового мира могут потребоваться изменения в конфигурации, но некоторые из изменений могут не работать со старым миром. Следовательно, используются два разных этапа обновления конфигурации. В основной части процесса обновления выполняется только замена или добавление файлов. Существующие файлы при этом не удаляются. Поскольку это может повлечь проблемы, в `/usr/src/UPDATING` содержится информация о том, какие из файлов и на каком шаге нужно удалить вручную.

Исходя из этих соображений в следующей процедуре описана рекомендуемая последовательность обновления.

### Примечание:

Хорошей практикой является запись в файл вывода команды `make`. Если что-то пошло не так, копию сообщения об ошибке можно отправить в один из списков рассылки FreeBSD.

Проще всего использовать для этого `script` с параметром, задающим имя файла для сохранения всего вывода. Не сохраняйте вывод в `/tmp`, так как этот каталог может быть очищен при следующей перезагрузке. Более подходящим местом является `/var/tmp`. Запустите команду непосредственно перед перестроением мира, а после завершения процесса наберите `exit`:

    # script /var/tmp/mw.out
    Script started, output file is /var/tmp/mw.out

Процедура 21.2. Обзор процесса построения мира

Команды для построения мира должны запускаться в указанном здесь порядке. В этом разделе даётся краткое описание назначения каждой из команд.

1. Если процесс построения мира уже запускался ранее на этой системе, то в `/usr/obj` могла остаться копия предыдущей сборки. Удалите этот каталог для ускорения процесса построения нового мира и возможного сокращений работы по разрешению зависимостей.

       # chflags -R noschg /usr/obj/*
       # rm -rf /usr/obj

2. Скомпилируйте новый компилятор и несколько сопутствующих инструментов и используйте их для компиляции остальной части мира. Результаты сохраняются в `/usr/obj`.

       # cd /usr/src
       # make buildworld

3. Для построения нового ядра используйте компилятор, расположенный в `/usr/obj`, чтобы защититься от ошибок несоответствия между компилятором и ядром. Это необходимо, так как определённые структуры данных могут поменяться, и при использовании различных версий ядра и исходных текстов перестанут работать `ps` и `top`.

       # make buildkernel

4. Установите новое ядро и модули, чтобы их можно было использовать для загрузки. Если используется `kern.securelevel` со значением выше `1` и на файле ядра установлен `noschg` или подобный флаг, то для этого сперва придётся дополнительно перейти в однопользовательский режим. В противном случае эту команду можно без проблем запустить в многопользовательском режиме. Смотрите страницу Справочника init(8) для получения информации о `kern.securelevel`, а также chflags(1) для информации об использовании различных файловых флагов.

       # make installkernel

5. Переведите систему в однопользовательский режим для минимизации проблем при обновлении уже работающих исполняемых файлов. Это также уменьшит вероятность возникновения проблем при работе старого мира на новом ядре.

       # shutdown now

   После перехода в однопользовательский режим, запустите эти команды, если в системе используется UFS:

       # mount -u /
       # mount -a -t ufs
       # swapon -a

   Если используется ZFS, запустите другие две команды. В данном примере zpool называется `zroot`:

       # zfs set readonly=off zroot
       # zfs mount -a

6. Дополнительно: Если желаемая картография клавиатуры отличается от используемой по умолчанию US English, её можно изменить с помощью kbdmap(1):

       # kbdmap

7. Затем, если часы CMOS установлены на местное время (это так, если вывод date(1) не содержит правильное время и часовой пояс), выполните:

       # adjkerntz -i

8. Пересборка мира не включает в себя добавление или обновление конфигурационных файлов в `/etc`, `/var`, `/usr` и некоторых других каталогах. Следующим шагом является выполнение первоначального обновления файлов конфигурации в `/etc` для подготовки к новому миру. Следующая команда ограничивается сравнением файлов, необходимых для успешного выполнения цели `installworld`. В частности, на этом шаге могут быть добавлены новые пользовательские группы, служебные учётные записи и сценарии автозапуска, которые были добавлены во FreeBSD со времени последнего обновления. Это необходимо для их использования при выполнении шага `installworld`. Смотрите Раздел 21.6.4, <<Объединение файлов конфигурации>> для получения более подробных инструкций по этой команде:

       # mergemaster -p

9. Установите новый мир и служебные исполняемые файлы, находящиеся в `/usr/obj`.

       # cd /usr/src
       # make installworld

10. Обновите остальные файлы конфигурации.

        # mergemaster -iF

11. Удалите устаревшие файлы. Это важно, так как в противном случае они могут вызвать проблемы.

        # make delete-old

12. Теперь нужна полная перезагрузка системы для того, чтобы загрузить новое ядро и мир с использованием новых конфигурационных файлов.

        # reboot

13. Убедитесь, что перед удалением старых версий библиотек все установленные порты были пересобраны согласно инструкциям в Раздел 5.6.5, <<Обновление портов>>. По завершению удалите все старые библиотеки во избежание конфликтов с их новыми версиями. За подробным описанием этого шага обратитесь к Раздел 21.6.5, <<Удаление устаревших файлов и библиотек>>.

        # make delete-old-libs

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

### 21.6.2. Файлы конфигурации

В процессе построения мира используется несколько файлов конфигурации.

`Makefile`, расположенный в `/usr/src`, описывает правила и порядок построения программ, составляющих FreeBSD.

В make.conf(5) описаны параметры, доступные для `make`, а также несколько общих примеров имеется в `/usr/share/examples/etc/make.conf`. Добавляемые в `/etc/make.conf` параметры определяют поведение `make` при построении программ. Эти параметры действуют при каждом использовании `make`, включая компиляцию приложений из Коллекции Портов, компиляцию собственных программ на Си и построение операционной системы FreeBSD. Изменение некоторых настроек может иметь далекоидущие и порой неожиданные последствия. Прочтите комментарии в обоих местах и примите к сведению, что значения по умолчанию были выбраны как компромисс между производительностью и надёжностью.

Поведение при сборке операционной системы из исходных текстов задаётся в `/etc/src.conf`. В отличие от `/etc/make.conf`, содержимое `/etc/src.conf` влияет только на сборку самой операционной системы FreeBSD. Описание многих параметров, доступных в этом файле, имеется в src.conf(5). Будьте осторожны при выключении на первый взгляд ненужных модулей ядра или параметров сборки. Иногда между ними имеются неожиданные или неочевидные взаимозависимости.

### 21.6.3. Переменные и цели выполнения

Общий формат использования `make`:

    # make -x -DVARIABLE target

В этом примере параметр `-`x`` передаётся `make`. Обратитесь к странице Справочника make(1) для получения примеров использования имеющихся параметров.

Чтобы передать переменную, укажите её имя с использованием `-D`VARIABLE``. Поведение `Makefile` зависит от переменных. Они могут быть заданы в `/etc/make.conf` или указаны при использовании `make`. Например, эта переменная указывает, что библиотеки для профилирования собирать не нужно:

    # make -DNO_PROFILE target

Это соответствует настройке в `/etc/make.conf`:

    NO_PROFILE=    true     #    Обход построения библиотек для профилирования

`target` указывает программе `make` на то, что нужно сделать, а `Makefile` определяет доступные цели. Некоторые цели используются в процессе построения для разбиения его на этапы.

Разделение опций удобно по двум причинам. Во-первых, это позволяет выполнять сборку, не затрагивая компоненты рабочей системы. По этой причине можно спокойно запустить `buildworld` на машине, работающей в многопользовательском режиме. Но цель `installworld` всё же рекомендуется запускать в однопользовательском режиме.

Во-вторых, это позволяет использовать монтирование по NFS для обновления многих машин по сети согласно описанию в Раздел 21.7, <<Отслеживание исходных текстов для нескольких машин>>.

Параметр `-j` приводит к запуску нескольких одновременно работающих процессов `make`. Поскольку процесс компиляции больше всего требователен к подсистеме ввода/вывода, а не к производительности процессора, это можно использовать и на машинах с одним процессором.

Используйте следующую команду на машине с одним CPU, чтобы иметь до 4 одновременно работающих процессов. Опубликованные в списке рассылки практические замеры показывают, что в среднем это даёт наибольший выигрыш в производительности.

    # make -j4 buildworld

На многопроцессорной машине попробуйте подобрать значение между `6` и `10`, и посмотрите, как это отразится на скорости работы.

### Примечание:

Если при выполнении команды `make buildworld` были заданы значения каких-либо переменных, то при выполнении `make installworld` нужно задать те же самые переменные. При этом `-j` нельзя использовать совместно с `installworld`.

Например, если выполнялась эта команда:

    # make -DNO_PROFILE buildworld

то результат её выполнения должен устанавливаться командой:

    # make -DNO_PROFILE installworld

В противном случае вторая команда попытается установить библиотеки для профилирования, которые не компилировались на этапе выполнения команды `make buildworld`.

### 21.6.4. Объединение файлов конфигурации

Текст предоставил Tom Rhodes.

FreeBSD предоставляет утилиту mergemaster(8), которая является скриптом для оболочки Боурна и предназначена для определения разницы между конфигурационными файлами в каталоге `/etc` и конфигурационными файлами из дерева исходных текстов `/usr/src/etc`. Это является рекомендуемым способом синхронизации системных конфигурационных файлов с теми, что размещены в дереве исходных текстов.

Перед использованием `mergemaster` рекомендуется скопировать имеющийся каталог `/etc` в какое-нибудь безопасное место. `-R` задает выполнение рекурсивного копирования, а `-p` сохраняет даты и владельца файлов:

    # cp -Rp /etc /etc.old

При запуске `mergemaster` строит временное корневое окружение, начиная с `/`, и заполняет его различными системными конфигурационными файлами. Затем эти файлы сравниваются с текущими установленными в системе. Файлы, которые имеют отличия, будут выданы в формате diff(1), где знак `+` означает добавленные или изменённые строки, а знак `-` означает строки, которые будут либо полностью удалены, либо заменены на новый файл. Обратитесь к страницам справочной системы по команде diff(1) для получения более полной информации о формате выдачи отличий в файлах.

Затем `mergemaster` выдаст каждый файл, в котором есть изменения, с вариантами действий: удалить новый файл, упоминаемый здесь как временный, установить временный файл в его неизменённом виде, объединить временный файл с установленным на данный момент, либо просмотреть результат ещё раз.

Выбор удаления временного файла укажет `mergemaster` оставить текущий файл без изменений и удалить его новую версию. Делать это не рекомендуется. Чтобы получить помощь в любое время, наберите ? в приглашении `mergemaster`. Если пользователь выбирает пропуск файла, запрос появится снова, после того как будут обработаны все остальные файлы.

Выбор установки немодифицированного временного файла приведёт к замене текущего файла новым. Для большинства немодифицированных файлов это является подходящим вариантом.

Выбор варианта с объединением файла приведёт к вызову текстового редактора, содержащего текст обоих файлов. Файлы можно объединить, просматривая оба файла на экране и выбирая те части из обоих, которые подходят для окончательного варианта. При сравнении файлов нажатие l выбирает содержимое слева, нажатие r выбирает содержимое справа. В окончательном варианте будет файл, состоящий из обеих частей, который и будет установлен. Этот вариант обычно используется для файлов, настройки в которых изменялись пользователем.

Выбор повторного просмотра результатов выдаст разницу между файлами.

После того как утилита `mergemaster` закончит работу с системными файлами, она выдаст запрос относительно других параметров. Она может запросить перестроение файла паролей и завершится запросом на удаление оставшихся временных файлов.

### 21.6.5. Удаление устаревших файлов и библиотек

На основе заметок, которые предоставил Anton Shterenlikht.

В ходе жизненного цикла разработки FreeBSD файлы с их содержимым иногда становятся устаревшими. Это может быть вызвано тем, что функциональность реализуется в другом месте, сменился номер версии библиотеки или файл был целиком удалён из системы. Такие устаревшие файлы, библиотеки и каталоги следует удалять вместе с обновлением системы. Это не даст захламить систему старыми файлами, которые занимают место на диске и на архивных носителях. Кроме того, если в старой библиотеке имеется проблема безопасности или стабильности, такую систему следует обновить до более новой библиотеки, чтобы предотвратить крахи, вызванные работой старой версии. Файлы, каталоги и библиотеки, которые признаны устаревшими, перечислены в `/usr/src/ObsoleteFiles.inc`. Для удаления устаревших файлов в процессе обновления системы следует пользоваться следующими инструкциями.

После выполнения `make installworld` и последующего `mergemaster` проверьте наличие устаревших файлов и библиотек:

    # cd /usr/src
    # make check-old

Если были найдены какие-либо устаревшие файлы, их можно удалить с помощью следующей команды:

    # make delete-old

Перед удалением каждого устаревшего файла запрашивается подтверждение. Используйте `BATCH_DELETE_OLD_FILES`, чтобы сократить этот процесс и позволить системе удалить эти файлы автоматически:

    # make -DBATCH_DELETE_OLD_FILES delete-old

Аналогичного эффекта можно достичь, пропустив эти команды через `yes`:

    # yes|make delete-old

### Предупреждение:

Удаление устаревших файлов приведёт к нарушению работы программ, которые всё ещё зависят от этих устаревших файлов. Это особенно верно для старых библиотек. В большинстве случаев программы, порты или библиотеки, использующие такую старую библиотеку, нужно перекомпилировать перед выполнением `make delete-old-libs`.

Программы для проверки наличия зависимостей от совместно используемых библиотек включают в себя sysutils/libchk и sysutils/bsdadminscripts.

Устаревшие совместно используемые библиотеки могут конфликтовать с более новыми библиотеками, что приводит к сообщениям следующего вида:

    /usr/bin/ld: warning: libz.so.4, needed by /usr/local/lib/libtiff.so, may conflict with libz.so.5
    /usr/bin/ld: warning: librpcsvc.so.4, needed by /usr/local/lib/libXext.so, may conflict with librpcsvc.so.5

Для решения этих проблем выясните, какой именно порт установил данную библиотеку:

    # pkg which /usr/local/lib/libtiff.so
      /usr/local/lib/libtiff.so was installed by package tiff-3.9.4
    # pkg which /usr/local/lib/libXext.so
      /usr/local/lib/libXext.so was installed by package libXext-1.1.1,1

Затем данный порт нужно удалить, пересобрать и переустановить. Для автоматизации этого процесса можно использовать ports-mgmt/portmaster. После того как все порты пересобраны и более не используют старые библиотеки, удалите эти старые библиотеки с помощью следующей команды:

    # make delete-old-libs

Если что-то работает неправильно, можно с лёгкостью перестроить конкретную часть системы. Например, если файл `/etc/magic` был случайно удалён в процессе обновления или переноса `/etc`, то команда `file` перестанет работать. В таком случае это можно исправить вот так:

    # cd /usr/src/usr.bin/file
    # make all install

### 21.6.6. Вопросы общего характера

Нужно ли полностью перестраивать систему при каждом изменении?

  Это зависит от характера изменения. Например, если svn показывает, что с момента последнего запуска были изменены только следующие файлы:

      src/games/cribbage/instr.c
      src/games/sail/pl_main.c
      src/release/sysinstall/config.c
      src/release/sysinstall/media.c
      src/share/mk/bsd.port.mk

  то перестраивать всю систему возможно незачем. Вместо этого можно перейти в соответствующие подкаталоги и выдать команду `make all install`. Однако если меняется что-то важное, например, `src/lib/libc/stdlib`, то вы должны перестроить всю систему.

  Некоторые пользователи перестраивают систему каждые две недели, позволяя изменениям накопиться за это время. Другие перестраивают только те вещи, которые менялись, и внимательно отслеживают все зависимости. Всё это зависит от того, как часто пользователь хочет делать обновление и отслеживает ли он FreeBSD-STABLE или FreeBSD-CURRENT.

Почему прерывается компиляция с большим количеством ошибок по сигналу 11 (или с другим номером сигнала)?

  Как правило, это говорит о проблемах с оборудованием. Построение системы является эффективным стресс-тестом для оборудования, в особенности памяти. Явным указателем на это является то, что при перезапуске make процедура построения прекращается в различные моменты времени.

  Для исправления этой ошибки попробуйте заменить комплектующие машины, начиная с оперативной памяти, для определения сбоящей компоненты.

Можно ли удалить `/usr/obj` после окончания?

  В этом каталоге содержатся все объектные файлы, которые создаются во время фазы компиляции. Обычно одним из первых шагов в процессе `make buildworld` является удаление этого каталога, чтобы начать заново. Сохранение `/usr/obj` после окончания имеет мало смысла, а его удаление освободит приблизительно 2 ГБ дискового пространства.

Могут ли быть продолжены прерванные процессы построения?

  Это зависит от того, насколько далеко зашел процесс построения перед тем, как была обнаружена проблема. В общем случае процесс `make buildworld` строит новые копии необходимых инструментальных средств и системные библиотеки. Затем эти средства и библиотеки устанавливаются. Новые инструментальные средства и библиотеки затем используются для перестроения самих себя и повторно устанавливаются. Система в целом теперь перестраивается с новыми системными файлами.

  На последней стадии выполнение этих команд является достаточно безопасным, поскольку они не отменяют работу предыдущего `make buildworld`:

      # cd /usr/src
      # make -DNO_CLEAN all

  Если в выводе `make buildworld` появляется такое сообщение:

      --------------------------------------------------------------
      Building everything..
      --------------------------------------------------------------

  то делать так вероятно достаточно безопасно.

  Если такое сообщение не выводится, всегда лучше подстраховаться и запустить сборку с самого начала.

Можно ли ускорить сборку мира?

  Ускорить процесс сборки мира может несколько действий. Например, весь процесс можно выполнять в однопользовательском режиме. Однако, это не позволит пользователям иметь доступ к системе, пока этот процесс не завершится.

  Тщательный подход к проектированию файловой системы или использование датасетов ZFS позволит почувствовать разницу. Задумайтесь о размещении `/usr/src` и `/usr/obj` на различных файловых системах. По возможности размещайте файловые системы на различных дисках и дисковых контроллерах. При монтировании `/usr/src` используйте параметр `noatime`, который отключает запись информации о времени доступа к файлу. Если `/usr/src` не расположен на собственной файловой системе, подумайте о перемонтировании `/usr` с `noatime`.

  Файловая система, на которой располагается `/usr/obj`, может быть смонтирована (или перемонтирована) с параметром `async`. Это приведёт к тому, что операции записи на диск будут выполняться асинхронно. Другими словами, запись будет завершаться немедленно, но данные записываться на диск несколькими секундами позже. Это позволит объединять операции записи и приведёт к значительному приросту производительности.

  Файловую систему с `/usr/obj` можно смонтировать с `async` для записи на диск в асинхронном режиме. В этом случае операции записи завершаются мгновенно, а сами данные записываются на диск через несколько секунд. Это позволяет писать кластеризованно, что может дать значительный прирост производительности.

  ### Предупреждение:

  Имейте в виду, что эта опция делает вашу файловую систему менее устойчивой. С этой опцией имеется больше шансов, что при перезагрузке машины после неожиданного сбоя при пропадании напряжения файловая система окажется в невосстановимом состоянии.

  Если каталог `/usr/obj` - это всё, что есть на этой файловой системе, то это не проблема. Если на той же самой файловой системе имеются какие-то важные данные, то проверьте давность ваших резервных копий перед включением этой опции.

  Выключите генерацию профилирующего кода, установив <<NO_PROFILE=true>> в файле `/etc/make.conf`.

  Передайте утилите make(1) параметр `-j`n`` для запуска параллельно нескольких процессов. Обычно это помогает вне зависимости от того, сколько процессоров установлено в машине.

Что делать, если что-то пошло не так?

  Скрупулезно проверьте, чтобы в вашем окружении не было мешающих остатков от предыдущих построений:

      # chflags -R noschg /usr/obj/usr
      # rm -rf /usr/obj/usr
      # cd /usr/src
      # make cleandir
      # make cleandir

  Да, команду `make cleandir` действительно нужно выполнять дважды.

  После этого повторите весь процесс снова, начиная с `make buildworld`.

  Если у вас всё ещё есть проблемы, пришлите текст ошибки и вывод команды `uname -a` в Список рассылки, посвящённый вопросам и ответам пользователей FreeBSD. Будьте готовы ответить на другие вопросы о конфигурации вашей системы!

Пред. | Наверх | След.
21.5. Синхронизация исходных текстов | Начало | 21.7. Отслеживание исходных текстов для нескольких машин

Этот, и другие документы, могут быть скачаны с https://download.freebsd.org/ftp/doc/.

По вопросам, связанным с FreeBSD, прочитайте документацию прежде чем писать в <questions@FreeBSD.org>.
По вопросам, связанным с этой документацией, пишите в рассылку <doc@FreeBSD.org>.