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 から呼ばれる順に書いてあります)。

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

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

初めて 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 ですが、たくさんの部分を書き換える必要がありますので注意してください。 どこを書き換えればよいのかについては、コメントを読めば十分理解できると思います。

警告:

newfs(8) コマンドには注意してください。 マウントずみのパーティションに新しいファイルシステムを作成することはできないものの、 このスクリプトはマウントされていない /dev/da0s1a, /dev/da0s1e, /dev/da2s1e をすべて削除します。 ひとつ間違えれば、あなたの環境を破壊してしまう可能性がありますので、 デバイス名の変更は注意深く行なってください。

# このファイル: stage_1.conf.default は stage_1.sh から読み込まれます。
#
# $FreeBSD: head/ja_JP.eucJP/articles/fbsd-from-scratch/stage_1.conf.default 38826 2012-05-17 19:12:14Z hrs $
#
# Original Revision: 1.3

# 新しいシステムを作成する場所を示すルートマウントポイントを指定。
# マウントポイントとして使われるだけなので、マウントポイントのある
# ファイルシステムにファイルは置かれず、書き込みはすべてマウントした
# ファイルシステムに行なわれる。
DESTDIR="/newroot"

# src ツリーのある場所。
SRC="/usr/src"

# make buildkernel KERNCONF=... で指定するカーネルコンフィグレーションファイル名。
KERNCONF="HAL9000"

# 利用できるタイムゾーンは /usr/share/zoneinfo 以下のファイルに記載されている。
TIMEZONE="Europe/Berlin"

#
# create_file_systems 関数は、DESTDIR 下にマウントポイントを作成し、
# ファイルシステムを作成し、DESTDIR 下にマウントしなければならない。
#
create_file_systems () {
  # 新しいルートファイルシステムを作成する。必須。
  # DEVICE を変更すること。変更しないとシステムが壊れる危険性がある。
  # grub から起動したい場合は、ルートファイルシステム作成には
  # newfs -O 1 を使わなければならない。
  DEVICE=/dev/da0s1a
  mkdir -m 755 -p ${DESTDIR}
  chown root:wheel ${DESTDIR}
  newfs -U -O 1 ${DEVICE}
  mount -o noatime ${DEVICE} ${DESTDIR}

  # その他のファイルシステムと初期マウントポイント。オプション。
  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
}

#
# create_etc_fstab 関数は、create_file_systems で作成されたファイルシ
# ステムに対応する fstab を生成しなければならない。
#
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
}

#
# copy_files 関数は、mergemaster が実行される前にファイルをコピーするのに
# 使われる。
#
copy_files () {
  # 好みに応じて、このリストに追加・削除すること。ほとんどの場合は必須。
  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
}

#
# ほかに新しいシステムで調整したいことすべて。
# 注意: あまり多くのバイナリをこの時点でインストールしないこと。稼働している
# 古いシステムと、インストールした新しいバイナリ・ヘッダを組み合わせると、
# ブートストラップ問題に陥る可能性がある。ports は新しいシステムが起動した後に
# 再構築する方がよい。
#
all_remaining_customization () {
  # compat シンボリックリンクがないと、linux_base のファイル群が
  # ルートファイルシステムに置かれてしまう。
  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

  # 私の好みは tmp を var/tmp にシンボリックリンクすること。オプション。
  cd ${DESTDIR}; rmdir tmp; ln -s var/tmp

  # /etc/printcap で指定したスプールディレクトリを作成。
  cd ${DESTDIR}/var/spool/output/lpd; mkdir -p as od ev te lp da
  touch ${DESTDIR}/var/log/lpd-errs

  # /home パーティションを共有していなければコピーした方がよいかも知れない。
  # mkdir -p ${DESTDIR}/home
  # cd /home; tar cf - . | (cd ${DESTDIR}/home; tar xpvf -)

  case ${REVISION} in
  4.*)
    # 4.x には devfs がないので、ハードウェアに合わせて非標準のデバイスを作成する。
    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' は /dev にしかデバイスを作成できないので、cpio を使う。
      cd /dev; find vinum -print | cpio -pv ${DESTDIR}/dev
    fi

    # floppy に wheel グループが書き込めるようにする。
    chown root:wheel ${DESTDIR}/dev/fd0*
    chmod g+w ${DESTDIR}/dev/fd0*
    ;;

  5.*)
    # floppy に wheel グループが書き込めるようにする。
    printf '%s\n' 'own  fd0 root:wheel' >> ${DESTDIR}/etc/devfs.conf
    printf '%s\n' 'perm fd0 0660'       >> ${DESTDIR}/etc/devfs.conf
    ;;

  *)
    printf '%s\n' "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 .

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

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

本文書、および他の文書は ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/ からダウンロードできます。

FreeBSD に関する質問がある場合には、 ドキュメント を読んだ上で <questions@FreeBSD.org> まで (英語で) 連絡してください。

本文書に関する質問については、 <doc@FreeBSD.org> まで電子メールを (英語で) 送ってください。