4. Этап первый: Установка системы

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

Скрипт с кодом для первого этапа называется stage_1.sh, и он запускается с единственным аргументом, например

# ./stage_1.sh default

будет считывать свою конфигурацию из файла stage_1.conf.default и записывать протокол в файл stage_1.log.default.

Далее приводится мой файл stage_1.conf.default. Вам необходимо подправить его в различных местах для того, чтобы он соответствовал вашим представлениям об ''идеальной системе''. Я попытался подробно прокомментировать те места, которые вы должны исправлять. Конфигурационный скрипт должен предоставлять четыре функции для оболочки, create_file_systems, create_etc_fstab, copy_files и all_remaining_customization (в случае, если это имеет смысл: именно в такой последовательности они будут вызываться из stage_1.sh).

Следует внимательно отнестись к следующим моментам:

  • Разбиение разделов.

    Я не являюсь сторонником наличия одного большого раздела для всей системы. Мои системы, как правило, имеют по крайней мере по одному разделу для /, /usr и /var с каталогом /tmp, образованным символической ссылкой в /var/tmp. Вдобавок я использую файловые системы в режиме совместного доступа к /home (домашние каталоги пользователей), /home/ncvs (копия CVS-хранилища FreeBSD), /usr/ports (дерево портов), /src (различные выгруженные из хранилища деревья исходных текстов) и /share (остальные совместно используемые данные, резервные копии которых не нужны, например, спул сервера телеконференций).

  • Новые возможности.

    Это то, что вы хотите иметь сразу после загрузки новой системы и даже до запуска второго этапа. Причина отказа от создания и перехода в chroot-окружение новой системы во время первого этапа и простой установки всех моих любимых портов заключается в том, что теоретически и практически существуют проблемы начальной загрузки и целостности: на первом этапе работает ваше старое ядро, однако в chroot-окружении содержатся новые двоичные файлы программ и файлы объявлений. Если новые программы используют новый системный вызов, то они будут завершаться SIGSYS, Плохой системный вызов, так как старое ядро не поддерживает этот новый вызов. Я наблюдал и другие проблемы при попытке построения порта lang/perl5.

Перед тем, как запускать stage_1.sh, убедитесь, что выполнили обычные действия при подготовке к make installworld installkernel, типа:

  • отредактировали конфигурационный файл вашего ядра

  • успешно выполнили make buildworld

  • успешно выполнили make buildkernel KERNCONF=whatever

Когда вы запускаете stage_1.sh первый раз, и конфигурационный файл, скопированный с работающей системы в новую, является устаревшим по сравнению с тем, что находится в каталоге /usr/src, mergemaster будет запрашивать вас на отработку этой ситуации. Я рекомендую переносить изменения. Если вам надоело отвечать на запросы, вы можете просто обновить файлы в вашей работающей системе за раз (Если только это вам подходит. Скорее всего, вам не нужно это делать, если одна из ваших систем работает под управлением -STABLE, а другая с -CURRENT. Изменения могут оказаться несовместимыми). Последующие вызовы утилиты mergemaster обнаружат, что RCS-идентификаторы версий соответствуют тем, что находятся в /usr/src, и пропустят файл.

Скрипт stage_1.sh остановится на первой команде, которая завершится неудачно (возвратит ненулевой код завершения) из-за set -e, так что вы не пропустите ошибки. Он также остановится, если вы используете отмену значения переменной окружения, как правило, из-за опечатки. Вы должны исправить все ошибки в вашей версии stage_1.conf.default перед тем, как продолжить работу.

В скрипте stage_1.sh мы вызываем mergemaster. Даже если никаким файлам объединение не требуется, он выведет сообщение и в конце сделает запрос

*** Comparison complete

Do you wish to delete what is left of /var/tmp/temproot.stage1? [no] no

Пожалуйста, ответьте no или просто нажмите Enter. Причина в том, что mergemaster оставит несколько файлов нулевой длины в каталоге /var/tmp/temproot.stage1, которые позже будут скопированы в новую систему (если их здесь уже нет).

После этого будет выдан список установленных файлов при помощи утилиты постраничного вывода, по умолчанию это more(1), может быть less(1):

*** You chose the automatic install option for files that did not
 exist on your system. The following were installed for you:
  /newroot/etc/defaults/rc.conf
  ...
  /newroot/COPYRIGHT

(END)

Нажмите q для того, чтобы прекратить просмотр. Затем вы будете проинформированы о login.conf:

*** You installed a login.conf file, so make sure that you run
 '/usr/bin/cap_mkdb /newroot/etc/login.conf'
 to rebuild your login.conf database

 Would you like to run it now? y or n [n]

Ответ не имеет значения, так как мы будем запускать cap_mkdb(1) в любом случае.

Вот авторский файл stage_1.conf.default, который вы должны потом модифицировать. В комментариях даётся достаточно информации о том, что необходимо изменить.

Внимание: Пожалуйста, обратите на команды newfs(8). Хотя вы не можете создавать новые файловые системы на смонтированных разделах, скрипт успешно удалит все несмонтированные разделы /dev/da0s1a, /dev/da0s1e и /dev/da2s1e. Этого может оказаться достаточным, чтобы испортить вам день, так что подправьте имена устройств.

# This file: stage_1.conf.default, sourced by stage_1.sh.
#
# $Id: stage_1.conf.default,v 1.2 2004/01/03 13:55:06 toor Exp toor $
# $FreeBSD: doc/en_US.ISO8859-1/articles/fbsd-from-scratch/stage_1.conf.default,v 1.3 2004/07/19 21:02:26 schweikh Exp $

# Root mount point where you create the new system. Because it is only
# used as a mount point, no space will be used on that file system as all
# files are of course written to the mounted file system(s).
DESTDIR="/newroot"

# Where your src tree is.
SRC="/usr/src"

# Your kernel config name as from make buildkernel KERNCONF=...
KERNCONF="HAL9000"

# Available time zones are those under /usr/share/zoneinfo.
TIMEZONE="Europe/Berlin"

#
# The create_file_systems function must create the mountpoints under
# DESTDIR, create the file systems, and then mount them under DESTDIR.
#
create_file_systems () {
 # The new root file system. Mandatory.
 # Change DEVICE names or risk foot shooting.
 # You must use newfs -O 1 for the root fs if you want to boot it from grub.
 DEVICE=/dev/da0s1a
 mkdir -m 755 -p ${DESTDIR}
 chown root:wheel ${DESTDIR}
 newfs -U -O 1 ${DEVICE}
 mount -o noatime ${DEVICE} ${DESTDIR}

 # Additional file systems and initial mount points. Optional.
 DEVICE=/dev/da0s1e
 mkdir -m 755 -p ${DESTDIR}/var
 chown root:wheel ${DESTDIR}/var
 newfs -U ${DEVICE}
 mount -o noatime ${DEVICE} ${DESTDIR}/var

 DEVICE=/dev/da2s1e
 mkdir -m 755 -p ${DESTDIR}/usr
 chown root:wheel ${DESTDIR}/usr
 newfs -U ${DEVICE}
 mount -o noatime ${DEVICE} ${DESTDIR}/usr
}

#
# The create_etc_fstab function must create an fstab matching the
# file systems created in create_file_systems.
#
create_etc_fstab () {
 cat <<EOF >${DESTDIR}/etc/fstab
# Device   Mountpoint   FStype Options    Dump Pass#
/dev/da0s1b  none    swap  sw     0 0
/dev/da1s1b  none    swap  sw     0 0
/dev/da2s2b  none    swap  sw     0 0
/dev/da3s2b  none    swap  sw     0 0
/dev/da0s1a  /     ufs  rw,noatime   1 1
/dev/da0s1e  /var    ufs  rw,noatime   1 1
/dev/da2s1e  /usr    ufs  rw,noatime   1 1
/dev/vinum/Share /share    ufs  rw,noatime   0 2
/dev/vinum/home /home    ufs  rw,noatime   0 2
/dev/vinum/ncvs /home/ncvs   ufs  rw,noatime   0 2
/dev/vinum/ports /usr/ports   ufs  rw,noatime   0 2
/dev/ad1s1a  /flash    ufs  rw,noatime   0 0
/dev/ad0s1  /2k     ntfs  ro,noauto   0 0
/dev/ad0s6  /linux    ext2fs ro,noauto   0 0
#
/dev/cd0   /cdrom    cd9660 ro,noauto   0 0
/dev/cd1   /dvd    cd9660 ro,noauto   0 0
proc    /proc    procfs rw     0 0
linproc   /compat/linux/proc linprocfs rw     0 0
EOF
 chmod 644 ${DESTDIR}/etc/fstab
 chown root:wheel ${DESTDIR}/etc/fstab
}

#
# The copy_files function is used to copy files before mergemaster is run.
#
copy_files () {
 # Add or remove from this list at your discretion. Mostly mandatory.
 for f in 
 /.profile 
 /etc/group 
 /etc/hosts 
 /etc/inetd.conf 
 /etc/ipfw.conf 
 /etc/make.conf 
 /etc/master.passwd 
 /etc/nsswitch.conf 
 /etc/ntp.conf 
 /etc/printcap 
 /etc/profile 
 /etc/rc.conf 
 /etc/resolv.conf 
 /etc/start_if.xl0 
 /etc/ttys 
 /etc/ppp/* 
 /etc/mail/aliases 
 /etc/mail/aliases.db 
 /etc/mail/hal9000.mc 
 /etc/mail/service.switch 
 /etc/ssh/*key* 
 /etc/ssh/*_config 
 /etc/X11/XF86Config-4 
 /var/cron/tabs/* 
 /var/files 
 /root/.profile 
 /boot/*.bmp 
 /boot/loader.conf 
 /boot/device.hints ; do
 cp -p ${f} ${DESTDIR}${f}
 done
}

#
# Everything else you want to tune in the new system.
# NOTE: Do not install too many binaries here. With the old system running and
# the new binaries and headers installed you are likely to run into bootstrap
# problems. Ports should be compiled after you have booted in the new system.
#
all_remaining_customization () {
 # Without the compat symlink the linux_base files end up on the root fs:
 cd ${DESTDIR}
 mkdir -m 755 usr/compat; chown root:wheel usr/compat; ln -s usr/compat
 mkdir -m 755 usr/compat/linux;  chown root:wheel usr/compat/linux
 mkdir -m 555 usr/compat/linux/proc; chown root:wheel usr/compat/linux/proc
 mkdir -m 755 boot/grub;    chown root:wheel boot/grub
 mkdir -m 755 linux 2k;    chown root:wheel linux 2k
 mkdir -m 755 src;     chown root:wheel src
 mkdir -m 755 share;     chown root:wheel share
 mkdir -m 755 dvd cdrom flash;  chown root:wheel dvd cdrom flash
 mkdir -m 755 home;     chown root:wheel home
 mkdir -m 755 usr/ports;    chown root:wheel usr/ports

 # My personal preference is to symlink tmp -> var/tmp. Optional.
 cd ${DESTDIR}; rmdir tmp; ln -s var/tmp

 # Make spooldirs for the printers in my /etc/printcap.
 cd ${DESTDIR}/var/spool/output/lpd; mkdir -p as od ev te lp da
 touch ${DESTDIR}/var/log/lpd-errs

 # If you do not have /home on a shared partition, you may want to copy it:
 # mkdir -p ${DESTDIR}/home
 # cd /home; tar cf - . | (cd ${DESTDIR}/home; tar xpvf -)

 case ${REVISION} in
 4.*)
 # 4.x without devfs: create non-standard devices to match your hardware.
 cd ${DESTDIR}/dev
 ./MAKEDEV all
 ./MAKEDEV da0 da0s1h da0s2h da0s3h da0s4h
 ./MAKEDEV da1 da1s1h da1s2h da1s3h da1s4h
 ./MAKEDEV da2 da2s1h da2s2h da2s3h da2s4h
 ./MAKEDEV da3 da3s1h da3s2h da3s3h da3s4h
 ./MAKEDEV bktr0 cd1
 if test -d /dev/vinum; then
  # 'vinum makedev' can only create devices in /dev, thus use cpio.
  cd /dev; find vinum -print | cpio -pv ${DESTDIR}/dev
 fi

 # Make the floppy group wheel writable.
 chown root:wheel ${DESTDIR}/dev/fd0*
 chmod g+w ${DESTDIR}/dev/fd0*
 ;;

 5.*)
 # Make the floppy group wheel writable.
 printf '%s
' 'own fd0 root:wheel' >> ${DESTDIR}/etc/devfs.conf
 printf '%s
' 'perm fd0 0660'  >> ${DESTDIR}/etc/devfs.conf
 ;;

 *)
 printf '%s
' "REVISION ${REVISION} not supported"
 exit 1
 ;;

 esac
}

# vim: tabstop=2:expandtab:shiftwidth=2:syntax=sh:
# EOF $RCSfile: stage_1.conf.default,v $

Сгрузите stage_1.conf.default.

При работе этот скрипт устанавливает систему, которая при загрузке имеет:

  • Унаследованные списки пользователей и групп.

  • Подключение к Internet по Ethernet и PPP с использованием межсетевого экрана.

  • Правильный временной пояс и NTP.

  • Другие более мелкие конфигурационные параметры, например, /etc/ttys и inetd.

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

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

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

Обновлено: 12.03.2015