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

# 23.6. Пересборка ''world''

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

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

> Обязательно сделайте резервную копию. И держите под рукой аварийную (fixit) дискету или загрузочный компакт диск. Может быть, вам никогда не приходилось ими пользоваться, но, постучав по дереву, всегда лучше подготовиться, чем потом сожалеть.

> Подпишитесь на соответствующий список рассылки: Ветки FreeBSD-STABLE и FreeBSD-CURRENT кода по природе своей являются изменяющимися. В разработке FreeBSD участвуют люди, и время от времени случаются ошибки.

> Иногда эти ошибки достаточно безобидны и приводят к выводу нового диагностического сообщения. Бывает, что изменение оказывается катастрофическим, и система не может загрузиться или разрушаются файловые системы (или что-нибудь ещё хуже).

> Если возникают подобные проблемы, в соответствующем списке рассылки публикуется сообщение ''heads up'', в котором описывается природа проблемы и затрагиваемые системы. Когда проблема решается, публикуется сообщение ''all clear''.

> Если вы пытаетесь отслеживать FreeBSD-STABLE или FreeBSD-CURRENT и не читаете Список рассылки, посвящённый обсуждению FreeBSD-STABLE или Список рассылки, посвящённый обсуждению FreeBSD-CURRENT соответственно, то вы напрашиваетесь на неприятности.

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

## 23.6.1. Канонический способ обновления вашей системы

Для обновления вашей системы вы должны прочесть `/usr/src/UPDATING` для выяснения шагов, которые нужно предпринять перед построением системы из вашей версии исходных текстов, а затем выполнить следующую последовательность действий:

    # cd /usr/src
    # make buildworld
    # make buildkernel
    # make installkernel
    # shutdown -r now

> Замечание: Есть несколько редких случаев, когда перед выполнением `buildworld` необходимо дополнительно запустить `mergemaster -p`. Они описаны в файле `UPDATING`. В общем случае вы можете без ущерба пропустить этот шаг, если не выполняете обновление с одной большой версии FreeBSD на другую.

После успешного выполнения `installkernel` вам необходимо загрузить систему в однопользовательском режиме (то есть посредством команды `boot -s`, заданной в приглашении загрузчика). После этого выполните:

    # mount -a -t ufs
    # mergemaster -p
    # cd /usr/src
    # make installworld
    # mergemaster
    # reboot

> Прочтите более полное описание: Описанная выше последовательность является только краткой выжимкой для того, чтобы помочь вам начать. Вы должны всё же прочесть последующие разделы для полного понимания каждого шага, особенно если собираетесь использовать собственную конфигурацию ядра.

## 23.6.2. Прочтите `/usr/src/UPDATING`

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

> Важно: Чтение `UPDATING` не заменит подписки на соответствующий список рассылки, как это и описано выше. Эти два условия являются дополняющими, а не взаимоисключающими друг друга.

## 23.6.3. Проверьте содержимое `/etc/make.conf`

Просмотрите файлы `/usr/share/examples/etc/make.conf` и `/etc/make.conf`. Первый содержит некоторые предопределенные по умолчанию значения – большинство из них закомментировано. Чтобы воспользоваться ими при перестроении системы из исходных текстов, добавьте их в файл `/etc/make.conf`. Имейте в виду, что все, добавляемое вами в `/etc/make.conf`, используется также каждый раз при запуске команды `make`, так что полезно задать здесь значения, подходящие вашей системе.

Вероятно стоит скопировать строки `CFLAGS` и `NO_PROFILE`, расположенные в `/usr/share/examples/etc/make.conf`, в файл `/etc/make.conf` и раскомментировать их.

Посмотрите на другие определения (`COPTFLAGS`, `NOPORTDOCS` и так далее) и решите, нужны ли они вам.

## 23.6.4. Обновите файлы в каталоге `/etc`

Каталог `/etc` содержит значительную часть информации о конфигурации вашей системы, а также скрипты, работающие в начале работы системы. Некоторые из этих скриптов меняются от версии к версии FreeBSD.

Некоторые конфигурационные файлы также используются в ежедневной работе системы. В частности, файл `/etc/group`.

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

Примером этого является добавление пользователя `smmsp`. Пользователи столкнулись с прерыванием процесса установки, когда mtree(8) пыталась создать `/var/spool/clientmqueue`.

Выходом является запуск утилиты mergemaster(8) в режиме, предваряющем построение системы, задаваемым опцией `-p`. Она будет сравнивать только те файлы, которые необходимы для успешного выполнения целей `buildworld` или `installworld`. Если ваша старая версия утилиты `mergemaster` не поддерживает опцию `-p`, воспользуйтесь новой версией из дерева исходных текстов при первом запуске:

    # cd /usr/src/usr.sbin/mergemaster
    # ./mergemaster.sh -p

> Подсказка: Если вы параноик, можете поискать файлы, владельцем которых является та группа, которую вы переименовываете или удаляете:

>     # find / -group GID -print

> выдаст список всех файлов, владельцем которых является группа `GID` (задаваемая именем или численным значением ID).

## 23.6.5. Перейдите в однопользовательский режим

Вам может понадобиться откомпилировать систему в однопользовательском режиме. Кроме обычного выигрыша в скорости процесса, переустановка системы затрагивает много важных системных файлов, все стандартные выполнимые файлы системы, библиотеки, include-файлы и так далее. Изменение их на работающей системе (в частности, в которой активно работают пользователи) может привести к неприятностям.

Другим способом является компиляция системы в многопользовательском режиме с последующим переходом в однопользовательский режим для выполнения установки. Если вы хотите поступить именно так, просто следуйте инструкциям до момента окончания построения. Вы можете отложить переход в однопользовательский режим до завершения целей `installkernel` или `installworld`.

Как администратор, вы можете выполнить:

    # shutdown now

на работающей системе, что переведет ее в однопользовательский режим.

Либо вы можете выполнить перезагрузку и в приглашении загрузчика выбрать пункт ''single user''. После этого система загрузится в однопользовательском режиме. В приглашении командного процессора вы должны запустить:

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

Эти команды выполняют проверку файловых систем, повторно монтируют `/` в режиме чтения/записи, монтируют все остальные файловые системы UFS, перечисленные в файле `/etc/fstab` и включат подкачку.

> Замечание: Если часы в вашей CMOS настроены на местное время, а не на GMT (это имеет место, если команда date(1) выдаёт неправильные время и зону), то вам может понадобиться запустить следующую команду:

>     # adjkerntz -i

> Это обеспечит корректную настройку местного часового пояса — без этого впоследствии вы можете столкнуться с некоторыми проблемами.

## 23.6.6. Удалите `/usr/obj`

При перестроении частей системы они помещаются в каталоги, которые (по умолчанию) находятся в `/usr/obj`. Структура повторяет структуру `/usr/src`.

Вы можете ускорить выполнение процесса `make buildworld` и, возможно, избавить себя от некоторой головной боли, связанной с зависимостями, удалив этот каталог.

На некоторых файлах из `/usr/obj` могут быть установлены специальные флаги (обратитесь к chflags(1) за дополнительной информацией), которые сначала должны быть сняты.

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

## 23.6.7. Перекомпилируйте исходные тексты базовой системы

### 23.6.7.1. Сохраните вывод

Неплохо сохранить вывод, получаемый при работе программы make(1), в файл. Если что-то вдруг пойдет не так, вы будете иметь копию сообщения об ошибке и полную картину того, где она произошла. Хотя это может и не помочь в определении причин происходящего, это может помочь другим, если вы опишите вашу проблему в одном из списков рассылки FreeBSD.

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

    # script /var/tmp/mw.out
    Script started, output file is /var/tmp/mw.out
    # make world
    … compile, compile, compile …
    # exit
    Script done, …

Если вы делаете это, не сохраняйте вывод в `/tmp`. Этот каталог может быть очищен при следующей перезагрузке. Лучше сохранить его в `/var/tmp` (как в предыдущем примере) или в домашнем каталоге пользователя `root`.

### 23.6.7.2. Компиляция базовых компонентов системы

Вы должны находиться в каталоге `/usr/src`:

    # cd /usr/src

(если, конечно, ваш исходный код не находится в другом месте, в случае чего вам нужно перейти в соответствующий каталог).

Для полного перестроения системы используется команда make(1). Эта команда читает инструкции из файла `Makefile`, описывающего, как должны быть перестроены программы, которые составляют систему FreeBSD, в каком порядке они должны быть построены и так далее.

Общий формат командной строки, которую вы будет набирать, таков:

    # make -x -DVARIABLE target

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

`-D`VARIABLE`` передает переменную в `Makefile`. Поведение `Makefile` определяется этими переменными. Это те же самые переменные, которые задаются в `/etc/make.conf`, и это — еще один способ их задания.

    # make -DNO_PROFILE=true target

является другим способом указания того, что библиотеки для профилирования строить не нужно, и соответствует строке

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

в файле `/etc/make.conf`.

`target` указывает программе make(1) на то, что вы хотите сделать. Каждый файл `Makefile` определяет некоторое количество различных ''целей'', и ваш выбор цели определяет то, что будет делаться.

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

В большинстве случаев вам не нужно передавать никаких параметров в make(1), так что ваша команда будет выглядеть примерно так:

    # make target

Замените `target` на одну или более из опций сборки. Первой из них всегда должна быть опция `buildworld`.

Как указывают на это названия, `buildworld` строит полностью новое дерево в каталоге `/usr/obj`, а `installworld` устанавливает это дерево на используемой машине.

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

Во-вторых, это позволяет вам использовать монтирование по NFS для обновления многих машин в сети. Если у вас есть три машины, `A`, `B` и `C`, которые вы хотите обновить, запустите `make buildworld` и `make installworld` на машине `A`. Хосты `B` и `C` должны будут затем смонтировать по NFS каталоги `/usr/src` и `/usr/obj` с машины `A`, и вы сможете запустить `make installworld` для установки результатов построения на машинах `B` и `C`.

Хотя цель `world` всё ещё имеется в наличии, вам настоятельно рекомендуется не пользоваться ею.

Выполните

    # make buildworld

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

На типичной машине с одним CPU вы должны запускать:

    # make -j4 buildworld

make(1) будет иметь до 4 одновременно работающих процессов. Эмпирические замеры, опубликованные как-то в списке рассылки, показывают, что в среднем это дает наибольшее увеличение производительности.

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

### 23.6.7.3. Время на построение

На время компиляции влияет множество факторов, но на данный момент современные машины справляются с построением дерева FreeBSD-STABLE примерно за 1-2 часа без дополнительных хитростей и убыстряющих процесс уловок. Дерево FreeBSD-CURRENT строится несколько дольше.

## 23.6.8. Откомпилируйте и установите новое ядро

Чтобы получить полную отдачу от вашей новой системы, вы должны перекомпилировать ядро. Это практически необходимость, так как отдельные структуры в памяти могут меняться, и программы типа ps(1) и top(1) не будут работать, пока версии ядра и исходных текстов системы не будут совпадать.

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

В FreeBSD важно выполнить buildworld перед сборкой нового ядра.

> Замечание: Если вы хотите построить собственное ядро и уже подготовили файл конфигурации, просто используйте `KERNCONF=`MYKERNEL`` следующим образом:

>     # cd /usr/src
>     # make buildkernel KERNCONF=MYKERNEL
>     # make installkernel KERNCONF=MYKERNEL

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

## 23.6.9. Перезагрузитесь в однопользовательский режим

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

## 23.6.10. Установите новые версии системных программ

Если вы компилировали достаточно свежую версию FreeBSD, в которой имеется команда `make buildworld`, то для установки новых версий программ вы должны теперь выполнить команду `installworld`.

Запустите

    # cd /usr/src
    # make installworld

> Замечание: Если при выполнении команды `make buildworld` вы задавали значения каких-либо переменных, то при выполнении `make installworld` вы должны задать те же самые переменные. Это не всегда так для остальных параметров; например, при выполнении `installworld` никогда не должен использоваться параметр `-j`.

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

>     # make -DNO_PROFILE buildworld

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

>     # make -DNO_PROFILE installworld

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

## 23.6.11. Обновите файлы, не обновленные по команде `make installworld`

При перестроении системы не будут обновляться некоторые каталоги (в частности, `/etc`, `/var` и `/usr`) с конфигурационными файлами.

Самым простым способом обновить такие файлы является запуск утилиты mergemaster(8), хотя можно сделать это и вручную, если вам так больше нравится. Вне зависимости от выбранного вами способа обязательно сделайте резервную копию каталога `/etc` на случай, если произойдёт что-то непредвиденное.

### 23.6.11.1. `mergemaster`

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

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

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

Затем mergemaster(8) выдаст вам каждый файл, в котором есть изменения, и в этот момент у вас есть возможность либо удалить новый файл (который будем считать временным), установить временный файл в его неизменённом виде, объединить временный файл с установленным на данный момент, либо просмотреть выдачу diff(1) ещё раз.

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

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

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

Выбор повторного просмотра diff(1)-разниц выдаст вам разницы между файлами, как это делала утилита mergemaster(8) до того, как запросила вас о выборе.

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

### 23.6.11.2. Обновление в ручном режиме

Однако если вы хотите произвести обновление вручную, то вы не можете просто скопировать файлы из `/usr/src/etc` в `/etc` и получить работающую систему. Некоторые из этих файлов сначала нужно ''установить''. Это нужно потому, что каталог `/usr/src/etc` не является копией того, что должен содержать ваш каталог `/etc`. Кроме того, есть файлы, которые должны присутствовать в `/etc`, но которых нет в `/usr/src/etc`.

Если вы используете mergemaster(8) (как это рекомендуется), то вы можете перейти сразу к следующему разделу.

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

> Сделайте резервную копию вашего каталога `/etc`: Хотя, в теории, никаких автоматических действий с этим каталогом не производится, всегда лучше чувствовать себя уверенным. Так что скопируйте имеющийся каталог `/etc` в какое-нибудь безопасное место. Запустите что-то вроде:

>     # cp -Rp /etc /etc.old

> `-R` задает выполнение рекурсивного копирования, а `-p` сохраняет даты, владельца файлов и тому подобное.

Вам нужно создать шаблонную структуру каталогов для установки нового содержимого `/etc` и других файлов. Подходящим местом является `/var/tmp/root`, и в нём потребуется разместить некоторое количество подкаталогов.

    # mkdir /var/tmp/root
    # cd /usr/src/etc
    # make DESTDIR=/var/tmp/root distrib-dirs distribution

Эти команды приведут к созданию нужной структуры каталогов и установке файлов. Множество каталогов, созданных в `/var/tmp/root`, будут пустыми и должны быть удалены. Проще всего сделать это так:

    # cd /var/tmp/root
    # find -d . -type d | xargs rmdir 2>/dev/null

Эти команды удалят все пустые каталоги. (Стандартный поток диагностических сообщений перенаправляется в `/dev/null` для исключения предупреждений о непустых каталогах.)

Теперь `/var/tmp/root` содержит все файлы, которые должны быть помещены в соответствующие места в `/`. Теперь пройдитесь по каждому их этих файлов и определите, чем они отличаются от имеющихся у вас файлов.

Заметьте, что некоторые из файлов, которые были установлены в каталог `/var/tmp/root`, имеют первым символом ''.''. На момент написания единственными такими файлами являлись файлы начальных скриптов командных процессоров в `/var/tmp/root/` и `/var/tmp/root/root/`, хотя могут быть и другие (зависит от того, когда вы это читаете). Обязательно пользуйтесь командой `ls -a`, чтобы выявить их.

Проще всего сделать это путём сравнения двух файлов при помощи команды diff(1):

    # diff /etc/shells /var/tmp/root/etc/shells

Эта команда покажет разницу между вашим файлом `/etc/shells` и новым файлом `/var/tmp/root/etc/shells`. Используйте это для определения того, переносить ли сделанные вами изменения или скопировать поверх вашего старого файла.

> Называйте новый корневой каталог (`/var/tmp/root`) по дате, чтобы вы смогли легко выявить разницу между версиями: Частое перестроение системы означает также и частое обновление `/etc`, которое может быть несколько обременительным.

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

> 1. Выполните перестроение системы обычным образом. Когда вы вам потребуется обновить `/etc` и другие каталоги, дайте целевому каталогу имя на основе текущей даты. Если вы делаете это 14 февраля 1998 года, то вы можете сделать следующее:

>        # mkdir /var/tmp/root-19980214
>        # cd /usr/src/etc
>        # make DESTDIR=/var/tmp/root-19980214 \
>            distrib-dirs distribution

> 2. Перенесите изменение из этого каталога, как это описано выше.

>    Не удаляйте каталог `/var/tmp/root-19980214` после окончания этого процесса.

> 3. Когда вы загрузите самую последнюю версию исходного кода и перестроите систему, выполните шаг 1. Это даст вам новый каталог, который может называться `/var/tmp/root-19980221` (если вы ждете неделю между обновлениями).

> 4. Теперь вы можете видеть изменения, которые были сделаны за прошедшую неделю, выполнив при помощи команды diff(1) рекурсивное сравнение двух каталогов:

>        # cd /var/tmp
>        # diff -r root-19980214 root-19980221

>    Как правило, здесь содержится гораздо меньше отличий, чем между каталогами `/var/tmp/root-19980221/etc` и `/etc`. Так как отличий меньше, то и легче перенести эти изменения в ваш каталог `/etc`.

> 5. Теперь вы можете удалить более старый из двух каталогов `/var/tmp/root-*`:

>        # rm -rf /var/tmp/root-19980214

> 6. Повторяйте этот процесс всякий раз, когда вам нужно перенести изменения в каталог `/etc`.

> Для автоматической генерации имён каталогов можно использовать команду date(1):

>     # mkdir /var/tmp/root-`date "+%Y%m%d"`

## 23.6.12. Перезагрузка

Теперь вы сделали всё. После того, как вы проверили, что всё на месте, можете перегрузить систему. Простая команда shutdown(8) должна это сделать:

    # shutdown -r now

## 23.6.13. Завершение

Теперь у вас имеется успешно обновлённая система FreeBSD. Поздравляем!

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

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

## 23.6.14. Вопросы?

23.6.14.1. Нужно ли полностью перестраивать систему при каждом изменении?
23.6.14.2. Компиляция прерывается с большим количеством ошибок по сигналу 11 (или с другим номером сигнала). Что случилось?
23.6.14.3. Могу ли я удалить каталог `/usr/obj` после окончания?
23.6.14.4. Могут ли быть продолжены прерванные процессы построения?
23.6.14.5. Как ускорить процесс построения системы?
23.6.14.6. Что мне делать, если что-то пошло не так?

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

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

    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.

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

Как правило, это говорит о проблемах с оборудованием. (Пере)построение системы является эффективным стресс-тестом для вашего оборудования и частенько выявляет проблемы с памятью. Обычно это проявляется в виде неожиданных сбоев компилятора или получения странных программных сигналов.

Явным указателем на это является то, что при перезапуске процедуры построения она прекращается в различные моменты времени.

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

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

Если отвечать коротко, то да.

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

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

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

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

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

Если вы на последнем шаге, и вы знаете это (потому что просматривали вывод, который сохраняете), то вы можете (достаточно безболезненно) выполнить команду:

    … исправление проблемы …
    # cd /usr/src
    # make -DNO_CLEAN all

При этом результат предыдущего запуска `make buildworld` откатываться не будет.

Если вы видите сообщение:

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

в выводе команды `make buildworld`, то делать так достаточно безопасно.

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

23.6.14.5. Как ускорить процесс построения системы?

- Работайте в однопользовательском режиме.

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

- Ещё лучше разместить эти файловые системы на нескольких дисках при помощи устройства ccd(4) (драйвер объединённых дисков).

- Выключите генерацию профилирующего кода (установив ''NO_PROFILE=true'' в файле `/etc/make.conf`). Вам это скорее всего никогда не понадобится.

- Также в `/etc/make.conf` установите значение `CFLAGS` во что-то типа `-O -pipe`. Оптимизация `-O2` выполняется гораздо медленнее, а разница между `-O` и `-O2` обычно несущественна. `-pipe` позволяет компилятору использовать для связи вместо временных файлов программные каналы, что уменьшает обращение к диску (за счет оперативной памяти).

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

- Файловая система, на которой располагается каталог `/usr/src`, может быть смонтирована (или перемонтирована) с опцией `noatime`. При этом запись на диск информации о времени последнего доступа к файлам будет отключена. Скорее всего, вам эта информация и не нужна.

      # mount -u -o noatime /usr/src

  > Внимание: В примере предполагается, что `/usr/src` располагается на собственной файловой системе. Если это не так (то есть он является частью, скажем, `/usr`), то вам нужно использовать точку монтирования той файловой системы, а не `/usr/src`.

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

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

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

      # mount -u -o async /usr/obj

  > Внимание: Как и раньше, если каталог `/usr/obj` располагается не на собственной файловой системе, то в примере замените его на имя соответствующей точки монтирования.

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

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

    # 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-questions. Будьте готовы ответить на другие вопросы о конфигурации вашей системы!

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

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

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