FreeBSD "с нуля"
Пред. |  | След.

# 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.4 2008/12/03 21:59:51 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"

    # Where your obj is.
    MAKEOBJDIRPREFIX="/usr/obj"

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

    # Your target architecture as used for make buildworld TARGET=...
    # If you did not specify a TARGET when building world, it defaulted
    # to the build architecture (run "uname -m" to find out if you are unsure).
    TARGET="i386"  # amd64 arm i386 ia64 mips pc98 powerpc sparc64 sun4v

    # 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.
      DEVICE=/dev/daXYZs1a
      mkdir -m 755 -p ${DESTDIR}
      chown root:wheel ${DESTDIR}
      newfs -U ${DEVICE}
      mount -o noatime ${DEVICE} ${DESTDIR}

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

      DEVICE=/dev/daXYZs1e
      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/devd.conf \
        /etc/devd.rules \
        /etc/exports \
        /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/src.conf \
        /etc/sysctl.conf \
        /etc/ttys \
        /etc/mail/aliases \
        /etc/mail/aliases.db \
        /etc/mail/hal9000.mc \
        /etc/mail/service.switch \
        /etc/ssh/*key* \
        /etc/ssh/*_config \
        /etc/X11/xorg.conf \
        /var/cron/tabs/* \
        /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

      # Create the ntp and slip log files.
      touch ${DESTDIR}/var/log/ntp ${DESTDIR}/var/log/slip.log

      # Make /usr/src point to the right directory. Optional.
      # Note: some ports need part of the src tree, e.g. emulators/kqemu,
      # sysutils/lsof, sysutils/fusefs, ...
      cd ${DESTDIR}/usr
      if test "${SRC}" != /usr/src; then
        rmdir src; ln -s ${SRC}
      fi
      if test "${MAKEOBJDIRPREFIX}" != /usr/obj; then
        rmdir obj; ln -s ${MAKEOBJDIRPREFIX}
      fi

      # 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 -)
    }

    # 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>.
Информация по подписке на эту рассылку находится на сайте проекта перевода.