12.4. Использование make world

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

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

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

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

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

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

Если вы пытаетесь отслеживать -STABLE или -CURRENT и не читаете списки рассылки или , то вы напрашиваетесь на неприятности.

12.4.1. Прочтите /usr/src/UPDATING

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

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

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

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

Как обычный пользователь (не разработчик FreeBSD), вам может потребоваться скопировать строки CFLAGS и NOPROFILE, расположенные в /etc/defaults/make.conf, в файл /etc/make.conf и раскомментировать их.

Версии 2.1.7 и ниже: Если в вашей машине имеется сопроцессор для работы с вещественными числами (машины класса 386DX, 486DX, Pentium и выше), то вы можете также раскомментировать строчку HAVE_FPU.

Это определение было убрано в версиях FreeBSD 2.2.2 и выше.

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

12.4.3. Обновите файл /etc/group

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

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

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

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

Выходом является просмотр файла /usr/src/etc/group и сравнение списка групп в нем с вашим собственным. Если в новом файле есть группы, отсутствующие в вашем, то скопируйте их. Таким же образом вы должны переименовывать все группы в /etc/group, которые имеют тот же самый GID, но другое название в /usr/src/etc/group.

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

    # find / -group GID -print
            

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

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

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

Если вы смелы и предупреждены о неприятностях, то можете пропустить этот шаг.

Версия 2.2.5 и выше: Как описывается более подробно ниже, в версиях FreeBSD 2.2.5 и выше процессы установки и построения разделены. Таким образом, вы можете построить новую систему в многопользовательском режиме, а для установки затем перейти в однопользовательский режим.

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

    # shutdown now
          

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

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

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

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

12.4.5. Удалите /usr/obj

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

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

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

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

12.4.6. Перекомпилируйте исходные тексты и установите новую систему

12.4.6.1. Все версии

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

    # cd /usr/src
            

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

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

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

    # make -x -DVARIABLE target
            

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

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

    # make -DNOPROFILE=true target
            

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

    NOPROFILE=    true
    #    Avoid compiling profiled libraries
            

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

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

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

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

    # make target
            

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

Неплохо сохранить вывод, получаемый при работе программы 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.

12.4.6.3. Версия 2.2.2 и ниже

/usr/src/Makefile содержит цель world, при выполнении которой система перестраивается и переустанавливается полностью.

Используйте ее вот так:

    # make world

12.4.6.4. Версия 2.2.5 и выше

Начиная с версии FreeBSD 2.2.5 (на самом деле впервые это было сделано в ветке -CURRENT, а затем адаптировано в -STABLE где-то между 2.2.2 и 2.2.5) цель world была разделена на две. buildworld и installworld.

Как указывают на это названия, 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 все еще существует, и вы можете использовать ее точно также, как это делается для версии 2.2.2. make world выполняет make buildworld, за которым следует make installworld.

Note: Если вы выполняете команды make buildworld и make installworld раздельно, вы должны передавать команде make(1) каждый раз одни и те же параметры.

Если вы запускаете:

    # make -DNOPROFILE=true buildworld
              

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

    # make -DNOPROFILE=true installworld
              

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

12.4.6.5. -CURRENT и выше

Если вы отслеживаете -CURRENT, вы можете также передать команде make параметр -j. Это позволит команде make запустить несколько параллельных процессов.

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

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

    # make -j4 target
            

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

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

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

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

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

Примите во внимание, что P6 с тактовой частотой 200МГц с более чем 32МБ ОЗУ и нормальными дисками SCSI выполняет команду make world примерно за полтора часа. P133 с 32МБ делает это за 5 или 6 часов. Увеличьте эти числа, если ваша машина медленнее...

12.4.7. Обновите файлы, не обновленные по команде make world

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

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

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

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

Сделайте резервную копию вашего каталога /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 и новым файлом /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"`
            

12.4.8. Обновите /dev

DEVFS: Если вы используете DEVFS, то вам это, скорее всего, делать не нужно.

Для безопасности этот процесс делается в несколько шагов.

  1. Скопируйте /var/tmp/root/dev/MAKEDEV в /dev.

        # cp /var/tmp/root/dev/MAKEDEV /dev
                  

    Если вы использовали mergemaster(8) для обновления /etc, то ваш скрипт MAKEDEV уже должен быть обновлен, так что его не нужно проверять (утилитой diff(1)) и копировать вручную в случае необходимости.

  2. Теперь выведите текущее содержимое вашего каталога /dev. Этот список должен содержать права, владельцев, старшее и младшее числа каждого файла, но не должен содержать информацию о времени. Проще всего это сделать, отрезав при помощи awk(1) часть информации.

        # cd /dev
        # ls -l | awk '{print $1, $2, $3, $4, $5, $6, $NF}' > /var/tmp/dev.out
                  
  3. Повторно создайте все устройства.

        # sh MAKEDEV all
  4. Создайте еще один список содержимого каталога, на этот раз в /var/tmp/dev2.out. Теперь просмотрите оба эти файла и поищите устройства, которые вы забыли создать. Таких быть не должно, но лишний раз удостовериться не помешает.

        # diff /var/tmp/dev.out /var/tmp/dev2.out
                  

    Скорее всего, вы заметите разногласия в именовании дисковых слайсов, что решается такими командами, как

        # sh MAKEDEV sd0s1
                    
    для повторного создания устройств слайсов. Точное название зависит от вашей системы и может отличаться от приведенного.

12.4.9. Обновите /stand

Note: Этот шаг описан только для полноты. Он может быть безболезненно пропущен.

В целях полноты обновления вам может потребоваться обновить также файлы в каталоге /stand. Эти файлы представляют собой жесткие ссылки на выполнимый файл /stand/sysinstall. Этот файл должен быть статически скомпонован, чтобы его работа не зависела от других файловых систем (в частности, от наличия смонтированной файловой системы /usr).

    # cd /usr/src/release/sysinstall
    # make all install
          

Исходные тексты, старее, чем 2 апреля 1998: Если ваш исходный код старше, чем 2 апреля 1998 или версия файла Makefile не равна 1.68 и выше (для текущих версий FreeBSD и систем 3.X) или 1.48.2.21 и выше (для систем 2.2.X), вам нужно добавить параметр NOSHARED=yes, как здесь;

    # make NOSHARED=yes all install
            

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

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

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

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

  • Такие команды, как ps(1), ifconfig(8) и sysctl(8) могут отказаться работать. Это может привести к невозможности подключиться к сети.

  • Могут не работать основные утилиты, такие, как mount(8), приводя к невозможности монтирования /, /usr и так далее. Скорее всего, этого не случится, если вы отслеживате кандидата на -STABLE, но весьма вероятно при отслеживании -CURRENT во время большого изменения.

  • Загружаемые модули ядра (LKM на системах до 3.X, KLD в системах 3.X и выше) строящиеся как часть "окружения", могут привести к сбою в работе старого ядра.

По этим причинам всегда лучше перестроить и установить новое ядро до перезагрузки.

Вы должны строить свое новое ядро после того, как завершили процесс make world (или make installworld). Если вы не хотите этого делать (может быть, вы хотите убедиться в построении ядра до обновления вашей системы), то у вас могут возникнуть проблемы. Это может происходить из-за того, что ваша команда config(8) старее, чем исходные тексты ядра.

В этом случае вы можете построить ваше ядро с новой версией config(8)

    # /usr/obj/usr/src/usr.sbin/config/config KERNELNAME
          

Во всех случаях это может и не работать. Рекомендуется, чтобы вы закончили выполнение команд make world (или make installworld) до компиляции нового ядра.

12.4.11. Перезагрузка

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

    # fastboot

12.4.12. Завершение

Вы должны иметь успешно обновленную систему FreeBSD. Поздравляем.

Вы можете заметить некоторые проблемы из-за того, что вы что-то забыли. Например, однажды я удалил /etc/magic в процессе обновления, перенес это в /etc, и команда file перестала работать. В результате недолгих размышлений оказалось, что команды

    # cd /usr/src/usr.bin/file
    # make all install
            
достаточно для исправления этой ситуации.

12.4.13. Вопросы?

12.4.13.1. Нужно ли полностью перестраивать систему при каждом изменении?
12.4.13.2. Компиляция прерывается с большим количеством ошибок по сигналу 11 (или с другим номером сигнала). Что случилось?
12.4.13.3. Могу ли я удалить каталог /usr/obj после окончания?
12.4.13.4. Могут ли быть продолжены прерванные процессы построения?
12.4.13.5. Могу ли я использовать одну машину как главную для обновления множества машин (NFS)?
12.4.13.6. Как ускорить процесс построения системы?

12.4.13.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, то перестрою всю систему или по крайней мере те ее части, которые скомпонованы статически (а также все остальное, что добавлял я и что статически скомпоновано).

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

И, конечно же, это все зависит от того, как часто вы хотите делать обновление, и отслеживаете ли вы -STABLE или -CURRENT.

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

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

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

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

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

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

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

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

Если вы хотите так поступать, то выполняйте построение, задавая переменную NOCLEAN утилите make, как это сделано здесь:

    # make -DNOCLEAN world
                

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

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

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

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

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

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

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

    --------------------------------------------------------------
    Building everything..
    --------------------------------------------------------------
                
в выводе команды "make world", то делать так достаточно безопасно.

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

12.4.13.5. Могу ли я использовать одну машину как главную для обновления множества машин (NFS)?

В списках рассылки FreeBSD часто задается вопрос о том, можно ли выполнять всю компиляцию на одной машине, а затем использовать результаты этой компиляции для выполнения команды make install на других машинах в сети.

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

Точные инструкции зависят от вашей версии FreeBSD

Вы все же должны будете обновить /etc и /dev на целевых машинах после выполнения этих рекомендаций.

Для 2.1.7 и ниже, Antonio Bemfica рекомендует такую последовательность действий:

    Date: Thu, 20 Feb 1997 14:05:01 -0400 (AST)
    From: Antonio Bemfica <[email protected]>
    To: [email protected]
    Message-ID: <[email protected]>

    Josef Karthauser спрашивал:

    > У кого-нибудь есть хороший метод обновления машин в сети

    Во-первых, выполните процедуры make world и так далее на вашей главной машине

    Во-вторых, смонтируйте / и /usr с удаленной машины:

    main_machine% mount remote_machine:/   /mnt
    main_machine% mount remote_machine:/usr /mnt/usr

    В-третьих, выполните 'make install' с целевым каталогом /mnt:

    main_machine% make install DESTDIR=/mnt

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

    Antonio
                

Этот механизм будет работать, если только (насколько я знаю) вы имеете право на запись в каталог /usr/src сервера NFS, так как цель install в 2.1.7 и ниже этого требует.

Между 2.1.7 и 2.2.0 появилась цель "reinstall". Вы можете действовать точно также, как это было описано для 2.1.7, но вместо "install" использовать "reinstall".

Эта схема не требует доступа с правом на запись к каталогу /usr/src на сервере NFS.

Между версиями 1.68 и 1.107 файла Makefile в этой цели присутствовала ошибка, которая приводила к тому, что доступ с правом записи к NFS-серверу все же требовался. Эта ошибка была исправлена до выхода FreeBSD версии 2.2.0, но может быть причиной ошибок, если у вас старый сервер, на котором работает -STABLE с тех времен.

Для версий 2.2.5 и выше вы можете воспользоваться целями "buildworld" и "installworld". Используйте их для построения дерева исходных текстов на одной машине, затем смонтируйте по NFS /usr/src и /usr/obj на удаленной машине и устанавливайте все здесь.

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

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

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

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

  • Выключите генерацию профилирующего кода (установив "NOPROFILE=true" в файле /etc/make.conf). Вам это практически никогда не нужно.

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

  • Передайте утилите make параметры -j<n> (если вы работаете с достаточно свежей версией FreeBSD) для запуска параллельно нескольких процессов. Это поможет вне зависимости от того, сколько процессоров установлено в вашей машине.

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

    Note: "noatime" есть в версии 2.2.0 и выше.

        # mount -u -o noatime /usr/src
                          

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

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

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

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

        # mount -u -o async /usr/obj
                        

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