FreeBSD をゼロから設定するには
Prev |  | Next

# 4. 第 1 段階: システムのインストール

この文書の初版では、第 1 段階にひとつのシェルスクリプトを使っていました。 カスタマイズはすべて、そのスクリプトを編集する必要があったのですが、 利用者からの意見を参考にして、スクリプトのコードとデータを分離することにしました。 そのため新しいスクリプトでは、コードスクリプトを変更せずに、 複数の異なるシステムに異なる構成のデータを置くことが可能になりました。

第 1 段階のコードスクリプトは `stage_1.sh` であり、次のように 1 個の引数をつけて実行すると

    # ./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` という、 4 個のシェル関数を提供しなければなりません (これは、 `stage_1.sh` から呼ばれる順に書いてあります)。

考慮すべき点は、以下のとおりです。

- パーティションの配置

  わたしは、システム全体を一つの大きな パーティションに入れるという考え方が好きではないので、 普通は `/`、 `/usr`、 `/var` の パーティションを分割し、`/tmp` を `/var/tmp` のシンボリックリンクにしています。 また、`/home` (ユーザのホームディレクトリ)、 `/home/ncvs` (FreeBSD CVS リポジトリの複製), `/usr/ports` (ports ツリー), `/src` (チェックアウトした src ツリー)、 `/share` (news スプールなど、バックアップする必要がない、 その他の共有データ) といったファイルシステムを、 古いシステムと新しいシステムで共有しています。

- その他の項目

  これは、新しいシステムの起動後にすぐに実行したいことや、 第 2 段階の前に実行したい内容のことです。 なぜ第 1 段階で単純に新しいシステムに chroot してお気に入りの ports をインストールしないのかというと、理論的にも、 実際の手順にも卵鶏問題があるからです。第 1 段階では、 古いカーネルが動作していますが、chroot 環境には、 新しいバイナリとヘッダが使われています。もしその新しいバイナリが、 古いカーネルには存在しない新しいシステムコールを使っていたら、 `SIGSYS, Bad system call` というエラーが出て停止してしまうでしょう。わたしは `lang/perl5` を構築する時にも問題が発生することを確認しています。

`stage_1.sh` を実行する前に、 `make installworld installkernel` を実行するために通常行なう作業を完了させておいてください。 これらは、たとえば次のようなものです。

- カーネルコンフィグファイルの設定

- `make buildworld` を正常終了させておくこと

- `make buildkernel KERNCONF=`whatever`` を正常終了させておくこと

初めて `stage_1.sh` を実行した場合は、 稼働中のシステムから新しいシステムへとコピーされる設定ファイルは `/usr/src` のものと比べると古いので、 `mergemaster` がどうするかを聞いてきます。 おすすめは、ここで変更点を統合しておくことです。 もし、何度も質問に答えるのが面倒であれば、 稼働中のシステムのファイルを更新しておきましょう (ただしこれは、そうできればの話です。 `-STABLE` のシステムを実行していて、 `-CURRENT` を構築する、 もしくはその逆のようなケースでは、そうしてはいけません)。 次に `mergemaster` を実行した時、 RCS バージョン ID が `/usr/src` にあるファイルと一致しているものは、処理が飛ばされるようになります。

`stage_1.sh` スクリプトは `set -e` が指定されており、 最初のコマンドが失敗 (終了コードが 0 以外) すると停止します。 そのため、エラーを見逃してしまうということはないでしょう。 これは、タイプミスなどで未定義の変数を使った場合にもエラーになります。 次に進む前に、`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` にサイズが 0 のファイルをいくつか残すからです。 これは、後で新しいシステムに (存在しなければ) コピーされます。

この後、インストールされたファイルのリストがページャ (デフォルトでは 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` ですが、たくさんの部分を書き換える必要がありますので注意してください。 どこを書き換えればよいのかについては、コメントを読めば十分理解できると思います。

> Warning 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` .

このスクリプトを実行すると、 起動した時に次のような状態になっているシステムがインストールされます。

- 稼働中のシステムと同じユーザとグループ

- Ethernet と PPP を経由した、 ファイアウォールありのインターネット接続環境

- 正しいタイムゾーンと NTP 設定

- `/etc/ttys` や `inetd` など、その他の細かな設定。

他の部分に対する設定は、第 2 段階が終わるまで動作しません。 たとえば、プリンタや X11 の設定ファイルもコピーされますが、 プリンタは PostScript® ユーティリティなど、 ベースシステムに含まれないアプリケーションを使うことが多いでしょう。 X11 はサーバ、ライブラリ、プログラムをコンパイルしないと動作しません。

Prev | Home | Next
前提とする環境 |  | 第 2 段階: ports のインストール