18.7. 「world」 の再構築
戻る | 第18章 FreeBSD のアップデートとアップグレード | 次へ

## 18.7. 「world」 の再構築

FreeBSD-STABLE、FreeBSD-CURRENT などの FreeBSD のどれか特定のバージョンについて、 ローカルのソースツリーを同期させたら、 そのソースツリーを使ってシステムを再構築できます。

### バックアップの作成:

システムを再構築する前に、 バックアップを作成することの重要性は、 いくら強調してもし過ぎると言うことはありません。 システム全体の再構築とは難しい作業ではありませんが、 どんなに注意していたとしても、 ソースツリーそのものに手違いがあった時には、 システムが起動しなくなってしまう状態になることがあるのです。

まず、バックアップがきちんと作成されていることを確認して、 起動可能インストールメディアを用意してください。 多分、それを使うことはないと思いますが、 あとで後悔することのないよう、念のため用意しておきましょう。

### メーリングリストに参加する:

もともと、FreeBSD-STABLE と FreeBSD-CURRENT のコードブランチは、 開発中のものです。 FreeBSD の作業に貢献してくださっている人達も人間ですから、 時にはミスをすることだってあるでしょう。

そのような間違いは、 単に警告を示す見慣れない診断メッセージをシステムが表示するような、 まったく害のないものであることもあれば、システムを起動できなくしたり、 ファイルシステムを破壊してしまうような、 恐ろしい結果を招くものかも知れません。

問題が生じた場合、 問題の詳細と、どのようなシステムが影響を受けるかについて書かれた 「注意 (heads up)」 の記事が適切なメーリングリストに投稿されます。 そして、その問題が解決されると、 「問題解決 (all clear)」 のアナウンス記事が同様に投稿されます。

FreeBSD-STABLE や FreeBSD-CURRENT ブランチを追随しているユーザで、 FreeBSD-STABLE メーリングリスト や FreeBSD-CURRENT メーリングリスト を読まないというのは、 自ら災難を招くようなものです。

訳注: これらのメーリングリストは英語でやりとりされているため、 日本語での投稿は歓迎されません。英語でのやりとりができない人は、 FreeBSD 友の会 の運営しているメーリングリストをあたってみるのがいいでしょう。

### `make world` は使わないこと:

古いドキュメントの中には、 `make world` を使うことを薦めているものがあります。 これは、重要な手順をいくつか抜かしてしまうので、 エキスパートでなければ使うべきではありません。 ほぼあらゆる場合において、`make world` を実行するのは間違っており、 ここで説明されている手順を用いるべきです。

### 18.7.1. システムを更新する正式な方法

システムを更新する前に、 `/usr/src/UPDATING` を読んでください。 このファイルには、用意したソースコードで buildworld を行う前に必要な手順が書かれています。 その後、以下の手順を踏んでください。

この節で説明するアップデートのプロセスは、古いコンパイラ、 古いカーネル、古い world、そして古いコンフィグレーションファイルからなる、 古いバージョンの FreeBSD をアップデートすることを想定しています。 ここで 「world」 は、コアシステムのバイナリ、ライブラリ、 プログラミングファイルを意味します。 コンパイラは 「world」 の一部ですが、 いくつか特別に気をつけなければならないことがあります。

また、これらのステップでは、 新しいバージョンのソースをすでに入手していることも仮定しています。 もしシステムのソースコードが古いようでしたら、 「ソースの同期」 を読んで、 ソースコードを新しいバージョンへ同期する方法の詳細を理解してください。

ソースからのシステムのアップデートは、 当初予想していたものよりとらえがたいものです。 長い年月において避けられない依存問題が判明したため、 FreeBSD の開発者達は、推奨されるアプローチを大きく変更しました。 この節では、現在推奨されているアップグレードの手順の背後にある、 理論的根拠について説明します。

連続したアップデートの手順は、以下の問題に対応している必要があります。

- 古いコンパイラは、 　 バグを含み新しいカーネルをコンパイルできない可能性があります そのため、新しいカーネルの構築には、 新しいコンパイラを使う必要があります。 ことのことは、新しいカーネルを構築する前に、 新しいコンパイラを構築していなければならないことを意味しています。 必ずしも、新しいカーネルを構築する前に、新しいコンパイラが インストールされている 必要があることを意味しているわけではありません。

- 新しい world は、 新しいカーネルの機能に依存している可能性があるため、 新しい world をインストールする前に、 新しいカーネルがインストールされていなければなりません。

これら 2 つの重要事項は、 以下の説明で中心となる `buildworld`, `buildkernel`, `installkernel`, `installworld` の基本です。 他の理由については以下でリストアップします。

- 古い world は、新しいカーネルでは正しく動かないかも知れません。 そのため、新しいカーネルをインストールしたら、 直ちに新しい world をインストールしてください。

- 設定の中には、新しい world をインストールする前に変更すべきものがありますが、 古い world を壊す可能性があります。 そのため、一般的に設定のアップデートは、 2 つの手順が必要です。

- 多くの場合、アップデートのプロセスは、ファイルを置き換えたり、 追加のみを行い、古いファイルを削除しません。 このことが問題を引き起こす可能性があります。 そのため、アップデートにおいては、 手動で削除すべきファイルがあることを、 特定のステップで指定することもあります。 これは将来自動化されるかもしれないし、されないかもしれません。

これらを配慮し、以下の推奨手順が作られました。 アップデートの細かい手順においては、追加の手順が必要になるかもしれませんが、 この中心となるプロセスは、しばらくの間変わっていません。

1. `make `buildworld``

   新しいコンパイラと関連ツールを最初にコンパイルし、 その後、新しいコンパイラで、 新しい world の残りの部分をコンパイルします。 コンパイルされたものは、 `/usr/obj` に格納されます。

2. `make `buildkernel``

   ここでは、 `/usr/obj` にある 新しい コンパイラが用いられます。 これにより、コンパイラとカーネルのミスマッチを防ぐことができます。

3. `make `installkernel``

   新しくアップデートされたカーネルで起動できるように、 新しいカーネルとカーネルモジュールをディスク上に配置します。

4. シングルユーザモードで再起動

   シングルユーザモードは、 すでに実行されているソフトウェアをアップデートする際の問題を最小限にします。 また、新しいカーネル上で古い world が実行される際の問題も最小限にします。

5. `mergemaster `-p``

   新しい world における最初の設定ファイルのアップデートを行います。 たとえば、新しいユーザグループをシステムに追加したり、 パスワードデータベースに対し、新しいユーザ名を追加するかもしれません。 前回のアップデート後に、 新しいグループや特別のシステムのユーザアカウントが追加された場合に、 `installworld` のステップで、 新しくインストールされたシステムのユーザまたはシステムのグループ名を問題なく使うことができるように、 この作業がときどき必要となります。

6. `make `installworld``

   world を `/usr/obj` からコピーします。 これで、ディスクには新しいカーネルと world が置かれたことになります。

7. `mergemaster`

   ディスクに新しい world が置かれたので、 残りの設定ファイルをアップデートします。

8. `make `delete-old``

   このターゲットは (使われなくなった) ファイルを削除します。 もし使われなくなったファイルがディスクに残っていると、 問題が起きる可能性があるため重要な作業です。 たとえば、古い `utmp.h` が残っていると、 新しい `utmpx.h` をインストールしたときに、 問題が起きる ports があります。

9. 再起動

   新しいカーネル、world そして設定ファイルがロードされたので、 再起動が必要です。

10. `make `delete-old-libs``

    使われなくなったライブラリが新しいライブラリと競合することを避けるため削除します。 古いライブラリを削除する前にすべての ports を再構築する必要があります。

もし、FreeBSD のあるブランチのあるリリースから、 同じブランチの最新リリースにアップデートするのであれば (たとえば 9.0 から 9.1)、 この手順にしたがわなくても良いでしょう。 なぜならば、コンパイラ、カーネル、ユーザランド、そして設定ファイルの間で、 重度のミスマッチが起きることはあまり考えられないためです。 マイナーなアップデートでは、新しいカーネルの構築とインストール後に、 古いアプローチである `make `world`` を用いてもうまくいくでしょう。

メジャーリリースをまたいだアップデートでは、 この方法を用いないと、何らかの問題にぶつかるでしょう。

大きなアップグレードにおいては、 installworld の前に特定のファイルの名前の変更や削除するといった、 特別な追加のステップが必要となることがあります。 `/usr/src/UPDATING` を注意深く読んでください。 特にファイルの最後には、 現在推奨されているアップグレードの手順が詳しく正確に説明されています。

この手続きは、 開発者たちがある種のミスマッチを完全に避けるために、長い年月をかけて進化してきました。 願わくば、この現在の手順が長い間安定してほしいものです。

まとめると、現在、ソースからの FreeBSD のアップグレードにおいて推奨されている方法は以下となります。

`#` `cd /usr/src` `#` `make buildworld` `#` `make buildkernel` `#` `make installkernel` `#` `shutdown -r now`

### 注記:

まれに `buildworld` の前に `mergemaster -p` を余分に実行することが必要な場合があります。その場合は `UPDATING` にそう書かれています。 FreeBSD のメジャーバージョンをまたいで更新するのでなければ、 通常はこの手順を省略してもなんら問題ないでしょう。

`installkernel` が無事に終了したら、ローダのプロンプトから `boot -s` を使ってシングルユーザモードで立ち上げてください。 それから、以下を実行してください。

`#` `mount -u /` `#` `mount -a -t ufs` `#` `adjkerntz -i` `#` `mergemaster -p` `#` `cd /usr/src` `#` `make installworld` `#` `mergemaster` `#` `make delete-old` `#` `reboot` `#` `make delete-old-libs`

### この後の説明を読んでください:

この後の節ではそれぞれのステップについて詳しく説明しています。 特にカスタムカーネルを利用する場合について説明しています。

### 18.7.2. `/usr/src/UPDATING` を読む

アップデートする前に、 `/usr/src/UPDATING` を読んでください。 このファイルには潜在的な問題や 特定のコマンドの順などの重要な情報が含まれています。 `UPDATING` がこの節に書かれているものと矛盾している時は `UPDATING` を優先してください。

### 重要:

`UPDATING` を読むということは、 適切なメーリングリストを購読する代わりにはなりません。 二つの要求は相補的なもので排他的なものではないのです。

### 18.7.3. `/etc/make.conf` の確認

make(1) のオプションの説明は、make.conf(5) や `/usr/share/examples/etc/make.conf` にあります。 これらの設定を `/etc/make.conf` に追加して、 make(1) の実行やプログラムの構築方法を設定してください。 ある設定を変更したことにより、影響が広い範囲におよび、 驚くべき結果をもたらす可能性があります。 両方のファイルに書かれているコメントを読むことと、 デフォルトの設定は、パフォーマンスと安全性の観点から選ばれていることを覚えておいてください。

`/etc/make.conf` で設定されたオプションは、 make(1) が使われる際には常に有効となります。 Ports Collection からアプリケーションをコンパイルする時、 ユーザが書いた C プログラムや FreeBSD オペレーティングシステムを構築する際に影響を及ぼします。

### 18.7.4. `/etc/src.conf` を確認する

`/etc/src.conf` は、 ソースコードを用いたオペレーティングシステムの構築についてコントロールします。 `/etc/make.conf` とは異なり、 `/etc/src.conf` に書かれた設定は、 FreeBSD オペレーティングシステムそのものを構築するときにのみ影響します。 このファイルで設定可能な多くのオプションについては、 src.conf(5) に記述されています。 一見したところ無効にされている、 使われていないカーネルモジュールやビルドオプションに注意してください。 ときどき予期しなかったり、わずかな影響を与えることがあります。

### 18.7.5. `/etc` にあるファイルの更新

`/etc` には、 システム起動時に実行されるスクリプトだけでなく、 システムの設定に関連する情報の大部分が含まれています。 そのディレクトリに含まれるスクリプトは、 FreeBSD のバージョンによって多少異なります。

設定ファイルのなかには、`/etc/group` のように稼働中のシステムが日々利用しているものもあります。

`make installworld` によるインストールの段階では、 特定のユーザ名、あるいはグループが存在していることを 要求する場面があります。システムのアップグレードを行なう際には、 それらのユーザ名やグループが削除、 あるいは変更されて存在していない可能性が考えられます。 `make buildworld` において、 それらのユーザ名やグループが存在するか確認が行われる場合もあります。

解決方法は、buildworld の前に `-p` をつけて mergemaster(8) を実行することです。 これを実行すると、`buildworld` や `installworld` が成功するために必要なファイルだけを比較します。

### ヒント:

名前を変更したり、削除してしまったグループが所有しているファイルを、 次のようにして調べることもできます。

`#` `find / -group `GID` -print`

このコマンドはグループ名もしくは数字で示されるグループ ID で指定されたグループ `GID` が所有するすべてのファイルを表示します。

### 18.7.6. シングルユーザモードへの移行

コンパイルは、シングルユーザモードで行なうことを考えてください。 システムの再インストールは重要なシステムファイル、 すべての標準システムのバイナリ、ライブラリ、インクルードファイルを操作します。 稼働中のシステムに (特に他のユーザがそのシステムにログインしている時に) そのような変更を加えることは、トラブルを引き起こす原因となります。

もう一つの方法として、マルチユーザモードでシステムを再構築して、 シングルユーザモードに移行してからそれをインストールする、 というのがあります。もしこのような方法で行ないたい場合は、 以下の手順を構築が完了するところまで飛ばしてください。 `installkernel` もしくは `installworld` を実行する際に、 シングルユーザモードに移行してください。

`#` `shutdown now`

あるいはシステムを再起動し、ブートプロンプトから 「single user」 オプションを選択してください。 シングルユーザモードで起動した後は、 シェルプロンプトから次のように実行してください。

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

これはファイルシステムをチェックした後、 `/` を読み書き可能にして再マウント、 `/etc/fstab` に指定されている、 それ以外の UFS ファイルシステムをすべてマウントしてから スワップを有効にします。

### 注記:

CMOS クロックが地域時間に設定されていて GMT ではない場合 (date(1) が正しい時間と地域を表示しないなら当てはまります)、 次のコマンドを実行すしてください。

`#` `adjkerntz -i`

こうすれば、 確実に地域時刻が正しく設定されます。

### 18.7.7. `/usr/obj` の削除

システムが再構築される時、構築されたものはデフォルトで `/usr/obj` 以下のサブディレクトリに格納されます。 そのディレクトリの下は `/usr/src` と同じ構造となります。

もしこのディレクトリが存在しているのであれば、 このディレクトリを削除して、 `make buildworld` の行程にかかる時間を短縮し、 依存問題に悩まされるようなトラブルを回避することができます。

`/usr/obj` 以下のファイルには、変更不可 (immutable) フラグがセットされているものがある可能性があります。 このようなファイルは最初に chflags(1) を用いてから削除する必要があります。

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

### 18.7.8. ベースシステムの再構築

#### 18.7.8.1. 出力メッセージの保存

実行される make(1) からの出力は、ファイルに保存すると良いでしょう。 もし、何か障害が発生した場合、エラーメッセージのコピーを FreeBSD メーリングリストに投稿してください。

ファイルに保存する最も簡単な方法は、script(1) コマンドを使い、引数に出力を保存したいファイル名を指定することです。 これを make world の直前に行ない、再構築が終了したら 以下のように `exit` と入力してください。

`#` `script /var/tmp/mw.out` Script started, output file is /var/tmp/mw.out `#` `make TARGET` … compile, compile, compile … `#` `exit` Script done, …

`/tmp` に出力を保存してはいけません。 このディレクトリは、次の再起動で削除されてしまう可能性があります。 出力の保存には、`/var/tmp` や `root` のホームディレクトリが適しています。

#### 18.7.8.2. ベースシステムの構築

`/usr/src` にて、 次のように実行してください。

`#` `cd /usr/src`

world を再構築するには、make(1) を使用してください。 このコマンドは、`Makefile` から、 FreeBSD を構成するプログラムの再構築方法や、 どういう順番でそれらを構築すべきかといったような指示を読み込みます。

コマンドラインの一般的な書式は、次のとおりです。

`#` `make -`x` -D`VARIABLE` `target``

この例では、`-`x`` が make(1) に渡されるオプションになります。 どのようなオプションが利用できるかについては、make(1) を参照してください。

`-D`VARIABLE`` は、 `Makefile` に渡される変数であり、 この変数は `Makefile` の動作をコントロールします。 また、`/etc/make.conf` で設定される変数も 同様です。これは変数を設定するもう一つの方法として用意されています。 たとえば以下の通りです。

`#` `make -DNO_PROFILE `target``

は、プロファイル版のライブラリを構築しないことを指定する もう一つの記法で、`/etc/make.conf` 中の

NO_PROFILE= true # Avoid compiling profiled libraries

の行に対応します。

`target` は、make(1) に どのように動作するのかを指示するためのものです。 各 `Makefile` には、数多くの異なる 「ターゲット (target)」 が定義されていて、 指定されたターゲットによって動作が決まります。

`Makefile` に書かれているターゲットには、 システムの再構築に必要な段階を、 多くのさらに細かい段階に分割するため、 構築の過程で利用されるものがあります。

大抵の場合、make(1) にパラメータを指定する必要はないでしょうから、 コマンドラインは次のようなものになります。

`#` `make `target``

ここで、`target` は、多くのビルドオプションのどれかになります。 最初のターゲットはいつも `buildworld` になるでしょう。

その名前が示すように、`buildworld` は `/usr/obj` 以下に新しい完全なディレクトリツリーを構築し、 `installworld` は、そのツリーを 現在のマシンにインストールします。

選択肢が分けられていることは、二つの理由から有用です。 まず第一に、構築作業は 「何にも依存せず独立して行なわれ」、 稼働中のシステムにまったく影響を与えません。 そのため、マルチユーザモードで稼働中のシステムでも、何一つ 悪影響を与えずに `buildworld` を 実行することができます。 ただし、`installworld` は シングルユーザモードで行なうことをおすすめします。

第二に、NFS マウントを利用することで、 ネットワーク上の複数のマシンをアップグレードすることが可能な点があげられます。 たとえば三台のマシン、 `A`, `B`, `C` をアップグレードしたい場合には、まずマシン `A` で `make buildworld` と `make installworld` を実行します。 それから、マシン `B` とマシン `C` でマシン `A` の `/usr/src` と `/usr/obj` を NFS マウントし、`make installworld` とすることで構築済みのシステムを各マシンにインストールできます。

`world` ターゲットも利用可能ですが、 このターゲットの利用は推奨されていません。

そのかわり、次のコマンド

`#` `make buildworld`

を実行してください。ここで `make` に `-j` をつけると、 同時に複数のプロセスを生成できます。 この機能はマルチ CPU マシンで特に効果を発揮します。 構築過程の大部分では CPU 性能の限界より I/O 性能の限界の方が問題となるため、シングル CPU マシンにも効果があります。

普通のシングル CPU マシンで以下のコマンド

`#` `make -j4 buildworld`

を実行すると、make(1) は最大 4 個までのプロセスを同時に実行します。 メーリングリストに投稿された経験的な報告によると、 4 個という指定が最も良いパフォーマンスを示すようです。

もし、複数の CPU を備えたマシンで SMP 設定が行なわれたカーネルを 利用しているなら、6 から 10 の間の値を設定し、速度がどれくらい 向上するか確認してみてください。

#### 18.7.8.3. システムの構築にかかる時間

構築時間を決める要素はさまざまありますが、 十分新しいマシンであれば、 トリックや近道を使わずに普通に構築した場合、FreeBSD-STABLE の構築には 1, 2 時間しかかからないでしょう。 FreeBSD-CURRENT の構築は、もう少し時間がかかります。

### 18.7.9. 新しいカーネルの構築とインストール

新しいシステムの全機能を完全に利用できるようにするには、 カーネルを再構築してください。 再構築は、ある種のメモリ構造体が変更された時には特に必須であり、 ps(1) や top(1) のようなプログラムは、 カーネルとソースコードのバージョンが一致しないと正常に動作しないでしょう。

最も簡単で安全にカーネルの再構築を行なう方法は、 `GENERIC` を使ったカーネルを構築・インストールすることです。 `GENERIC` にはあなたが必要とするデバイスがすべて含まれていない かも知れませんが、あなたのシステムをシングルユーザモードで 起動させるのに必要なものはすべて入っています。 これは新しいバージョンのシステムがきちんと動作するかどうか 調べる良い方法の一つです。 `GENERIC` で起動して、 システムが正常に動作しているかどうかを確かめたら、 カスタムカーネルコンフィグレーションファイルを使って新しいカーネルを構築してください。

FreeBSD では、新しいカーネルを構築する前に build world を行うことが重要です。

### 注記:

既にあるコンフィグレーションファイルを使ってカスタムカーネルを構築するには、 `KERNCONF=`MYKERNEL`` を使ってください。

`#` `cd /usr/src` `#` `make buildkernel KERNCONF=`MYKERNEL`` `#` `make installkernel KERNCONF=`MYKERNEL``

`kern.securelevel` を 1 より大きくしていて、 かつ カーネルのバイナリファイルに `noschg` のようなフラグを設定している場合は、 `installkernel` を行うのにシングルユーザモードに移行してください。 それ以外の場合は、 マルチユーザモードでこれらのコマンドを問題なく動かせるはずです。 `kern.securelevel` について詳しくは init(8) を、ファイルの様々なフラグについて詳しくは chflags(1) をご覧ください。

### 18.7.10. シングルユーザモードで再起動する

新しいカーネルが動作するかどうかテストするために、 シングルユーザモードで再起動してください。 シングルユーザモードでの起動は、 「シングルユーザモードへの移行」 に書かれている手順に従ってください。

### 18.7.11. 新しいシステムバイナリのインストール

次に、`installworld` を使って新しいシステムバイナリのインストールを行ないます。

`#` `cd /usr/src` `#` `make installworld`

### 注記:

`make buildworld` に変数を指定した場合は、同じ指定を `make installworld` にも指定しなければなりません。 ただし `-j` は `installworld` で絶対に使ってはいけません。

たとえば以下のように実行したなら、

`#` `make -DNO_PROFILE buildworld`

以下のようにしてインストールしなければなりません。

`#` `make -DNO_PROFILE installworld`

もしそうしなかった場合、 `make buildworld` の段階で構築されていない プロファイル版ライブラリをインストールしようとしてしまうでしょう。

### 18.7.12. `make installworld` で更新されないファイルの更新

システムの再構築は、いくつかのディレクトリ、 特に、`/etc` や `/var` や `/usr` において、 新規に導入されたり、変更された設定ファイルによる ファイルの更新は行なわれません。

これらのディレクトリのファイルを更新するもっとも簡単な方法は、 mergemaster(8) を使うことです。 必ず `/etc` のバックアップを取って不測の事態に備えてください。

#### 18.7.12.1. `mergemaster`

寄稿: Rhodes Tom [FAMILY Given].

mergemaster(8) は Bourne シェルスクリプトで、 `/etc` にある設定ファイルとソースツリーの `/usr/src/etc` にある設定ファイルの違いを確認するのを手伝ってくれます。 これを使うのが、ソースツリーにある設定ファイルにシステムの設定ファイルを 更新するために推奨される方法です。

始めるには、プロンプトから `mergemaster` と入力してください `mergemaster` は `/` を起点とした一時的なルート環境を構築し、 さまざまなシステム設定ファイルを (訳注: デフォルトでは `/var/tmp/temproot` に) 置いていきます。 これらのファイルは現在システムにインストールされているファイルと比較されます。 異なるファイルは diff(1) 形式で示され、 `+` の記号は追加または変更された行を表し、 `-` は完全に削除されたか新しく置き換えられた行を表します。 diff(1) の書式とファイルの違いの表示方法についてのより詳しい情報は、 diff(1) を参照してください。

mergemaster(8) は違いのあるファイルをそれぞれ示します。 新しいファイルを削除するか、 一時ファイルをそのままインストールするか、 一時ファイルと現在インストールされているファイルを統合するか、 もしくは diff(1) の結果をもう一度見るか選択できます。

一時ファイルの削除を選ぶと、mergemaster(8) に現在のファイルを変更しないで新しいバージョンを削除せよと伝えます。 この選択は、現在のファイルを変更する理由が分からないのであれば、 お勧めできません。 mergemaster(8) のプロンプトで ? とタイプすれば、 いつでもヘルプが見られます。 ファイルのスキップを選ぶと、他のすべてのファイルを終えたあと、 もう一度そのファイルが提示されます。

一時ファイルをそのままインストールすることを選ぶと、 現在のファイルを新しいファイルで置き換えます。 ほとんどの手を加えていないファイルは、 これが一番よい選択です。

ファイルの統合を選んだ場合、 テキストエディタが起動され、両方のファイルの中身が提示されます。 画面上に並ぶ両方のファイルを見て新しいファイルを作成するために両方から必要な部分を選択し、 2 つのファイルを統合することができます。 並んでいるファイルを比較するとき、 l で左側の中身を選択し、 r で右側の中身を選択します。 最終出力は左右両方の部分でできたファイルになるでしょう。 このファイルをインストールすることができます。 たいてい、このオプションはユーザが設定を変更したファイルに使われます。

diff(1) の結果をもう一度見る、を選択すると、 ちょうど先ほど mergemaster(8) が選択肢を表示する前と同じように、 ファイルの相異点を見ることができます。

mergemaster(8) がシステムファイルの比較を終えたあと、 他のオプションについてもプロンプトが表示されます。 mergemaster(8) が、パスワードファイルを再構築するかどうかを尋ねることがあります。 最後に残った一時ファイルを削除するかどうかを尋ねて終了します。

#### 18.7.12.2. 手動での更新

手動で更新する場合には、単にファイルを `/usr/src/etc` から `/etc` に コピーしないでください。正常に動作しないでしょう。 ファイルの中には、 「インストールという手順を踏まなければならないもの」 が含まれています。 `/usr/src/etc` は `/etc` にそのまま置き換えられるようなコピーでは ないからです。 また、`/etc` にあるべきファイルのうちで `/usr/src/etc` にないものもあります。

mergemaster(8) を (勧められた通り) 使っているのであれば、次の節 まで飛ばしてもかまいません。

手動で行う際の一番簡単な方法は、 ファイルを新しいディレクトリにインストールしてから、 以前のものと異なっている部分を調べて更新作業を行なうことです。

### 既存の `/etc` をバックアップする:

たとえば以下のようにして、 既存の `/etc` をどこか安全な場所にコピーしておきましょう。

`#` `cp -Rp /etc /etc.old`

ここで、`-R` は再帰的なコピーを行ない、 `-p` はファイルの更新時間や所有者などを保存します。

新しい `/etc` やその他のファイルをインストールするための、 仮のディレクトリを作ってください。

`#` `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` 以下にインストールされているファイルの中には、 「.」 から始まっているものがあります。 `ls -a` を使って確かめてください。

もっとも簡単な方法は、二つのファイルを比較するコマンド diff(1) を使うことです。

`#` `diff /etc/shells /var/tmp/root/etc/shells`

このコマンドは、`/etc/shells` ファイルと 新しい `/var/tmp/root/etc/shells` ファイルの異なる部分を表示します。 内容を確認して、書き換えたものに変更点をマージするか、 それとも既存のファイルを新しいもので上書きするかを判断してください。

### 新しい root ディレクトリ (`/var/tmp/root`) の名前に タイムスタンプを付けておくと、 異なるバージョン間の比較を楽に行なうことができます。:

頻繁にシステムの再構築を行なうということは、 `/etc` の更新もまた、 頻繁に行う必要があるということです。 これはちょっと手間のかかる作業です。

この作業は、あなたが `/etc` にマージした、 新しく変更されたファイルの最新のセットのコピーを保存しておくことで 素早く行なうことができます。

1. 普通に make world します。 `/etc` や 他のディレクトリを更新したくなったときは、ターゲット ディレクトリに、そのときの日付に基づく名前をつけてください。

   `#` `mkdir /var/tmp/root-20130214` `#` `cd /usr/src/etc` `#` `make DESTDIR=/var/tmp/root-20130214 \ distrib-dirs distribution`

2. 上に説明されているように、 このディレクトリから変更点をマージします。 その作業が終了しても、 `/var/tmp/root-20130214` を削除してはいけません。

3. 最新版のソースをダウンロードして再構築したら、 ステップ 1 にしたがってください。今度は、 新しい日付を反映したディレクトリを作成してください。 この例では、`/var/tmp/root-20130221` という新しいディレクトリをつくります。

4. diff(1) を使用し、 二つのディレクトリを比較する再帰的 diff を作成することで、 一週間の間に行なわれたソースへの変更による相違点を調べます。

   `#` `cd /var/tmp` `#` `diff -r root-20130214 root-20130221`

   これによって報告される相違点は、大抵の場合、`/var/tmp/root-20130221/etc` と `/etc` との相違点に比べて非常に少ないものになります。 相違点が少ないため、変更点を既存の `/etc` にマージすることは、比較的容易になります。

5. ここまで終了したら、 `/var/tmp/root-*` の二つのうち、古い方のディレクトリは削除して構いません。

   `#` `rm -rf /var/tmp/root-20130214`

6. この工程を、 `/etc` へ変更点をマージする必要があるたび、繰り返してください。

ディレクトリ名の生成を自動化するには、date(1) を利用してください。

`#` `mkdir /var/tmp/root-`date "+%Y%m%d"``

### 18.7.13. 使われなくなったファイル、ディレクトリの削除

ベースとなったノートの提供: Shterenlikht Anton [FAMILY Given].

FreeBSD の開発サイクルにおいて、 ファイルやシステムの一部が使われなくなることがあります。 それらの機能が別の場所で実装されたり、 ライブラリのバージョン番号が変わったり、 システムから完全に削除されることがあるためです。 システムのアップデート時に削除が必要になるのは、 古いファイル、ライブラリそしてディレクトリです。 これらのファイルを削除することで、 記憶媒体やバックアップ媒体において不必要な容量を占めている古いファイルが、 システム上に散乱することがなくなります。 また、古いライブラリのセキュリティや安定性に問題があると、 ライブラリを新しくしてシステムを安定な状態にし、 古いライブラリによりシステムがクラッシュすることを防がなければなりません。 使われなくなったファイル、ディレクトリ、ライブラリは `/usr/src/ObsoleteFiles.inc` にまとめられています。以下の手順により、 アップグレードの過程でこれらのファイルを削除できます。

`make `installworld`` と、その後の `mergemaster` が無事に終わったら、 以下の方法で使われなくなったファイルやライブラリを確認してください。

`#` `cd /usr/src` `#` `make check-old`

見つかった古いファイルは、以下のコマンドで削除できます。

`#` `make delete-old`

### ヒント:

その他のターゲットについては `/usr/src/Makefile` をご覧ください。

使われなくなったファイルを削除する際、 ファイルごとに確認が求められます。 確認を省略し、自動的にファイルを削除するには、 以下のように `BATCH_DELETE_OLD_FILES` を設定してください。

`#` `make -DBATCH_DELETE_OLD_FILES delete-old`

`yes` をコマンドへパイプでつなげても省略できます。

`#` `yes|make delete-old`

### 18.7.14. 再起動

すべてがあるべき正しい場所に存在することをチェックしたら、 shutdown(8) を実行してシステムを再起動してください。

`#` `shutdown -r now`

### 18.7.15. 使われなくなったライブラリの削除

### Warning:

使われなくなったファイルを削除すると、 削除したファイルに依存していたアプリケーションは壊れてしまいます。 特に、古いライブラリを削除する場合に起こり得ます。 通常、`make `delete-old-libs`` を実行する前に、 これらの古いライブラリを使っているプログラム、ports、 ライブラリを再構築する必要があります。

共有ライブラリをチェックするユーティリティとして、 Ports Collection の `sysutils/libchk` や `sysutils/bsdadminscripts` を利用できます。

使われなくなった共有ライブラリは、 新しいライブラリと競合し、以下のようなメッセージを表示することがあります。

/usr/bin/ld: warning: libz.so.4, needed by /usr/local/lib/libtiff.so, may conflict with libz.so.5 /usr/bin/ld: warning: librpcsvc.so.4, needed by /usr/local/lib/libXext.so, may conflict with librpcsvc.so.5

この問題を解決するには、 まずライブラリがどの port によってインストールされたかを調べて下さい。

`#` `pkg_info -W /usr/local/lib/libtiff.so` /usr/local/lib/libtiff.so was installed by package tiff-3.9.4 `#` `pkg_info -W /usr/local/lib/libXext.so` /usr/local/lib/libXext.so was installed by package libXext-1.1.1,1

見つかった port をアンインストールし、 再構築、再インストールしてください。 この過程は `ports-mgmt/portmaster` で自動化できます。 すべての ports が再構築され、 古いライブラリがどこにも使われていないことを確認したら、 以下のコマンドで古いライブラリを削除してください。

`#` `make delete-old-libs`

ここまで来れば、FreeBSD システムのアップグレードは成功です。 おめでとうございます。

もしちょっとした問題があった場合でも、 システムの一部を再構築するのは簡単です。 たとえば、アップグレードや `/etc` のマージの途中で誤って `/etc/magic` を削除してしまい、 その結果 file(1) が動作しなくなってしまったような場合には、 次のコマンドを実行して修復してください。

`#` `cd /usr/src/usr.bin/file` `#` `make all install`

### 18.7.16. 質問ですか?

18.7.16.1. 変更が行なわれたら、その度にシステムの再構築が必要になるのでしょうか?
18.7.16.2. signal 11 (もしくは他のシグナル番号) のエラーがたくさん出て コンパイルが失敗します。何が起こっているんでしょうか?
18.7.16.3. 終了したら /usr/obj を削除してもかまいませんか?
18.7.16.4. 構築を中断した場合、その構築を途中から再開することはできますか?
18.7.16.5. どのようにすれば make world を高速化できますか?
18.7.16.6. なにか悪いことがあったらどうすればいいですか?

18.7.16.1. | 変更が行なわれたら、その度にシステムの再構築が必要になるのでしょうか?

それは変更の性質によるので、なんとも言えません。 たとえば、svn を実行したとき、 次にあげるようなファイルが更新されていたとします。

`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` のような大きな変更が行なわれた場合には、 システム全体を再構築するか、 少なくとも静的にリンクされているものを作り直す必要があります。

結局のところ、 どの時点で現在のシステムをアップグレードするかはあなたが決めることです。 2 週間ごとにシステムを再構築し、その 2 週間の変更を取り込むユーザもいますし、 変更のあった部分だけ再構築し、 すべての依存関係を確かめたいと考えるユーザもいます。

それらはどのくらいの頻度でアップグレードしたいか、 そして FreeBSD-STABLE か FreeBSD-CURRENT のどちらを追いかけているのかによります。

18.7.16.2. | signal 11 (もしくは他のシグナル番号) のエラーがたくさん出て コンパイルが失敗します。何が起こっているんでしょうか?
| これは通常、ハードウェアに問題があることを示しています。 システムの再構築は、ハードウェアに対する負荷耐久試験を行なうための 有効な手段の一つで、メモリに関係する問題がよく報告されます。 その大部分は、 不可解な異常終了となることで発見されます。 本当にこの問題によるものかどうかは、make をもう一度実行し、 異なる段階で異常終了が発生するか、ということから確認できます。 このエラーに対応するには、マシンの部品を交換して、 どの部分が悪いのかを調べてみてください。
18.7.16.3. | 終了したら `/usr/obj` を削除してもかまいませんか?

一言で答えるなら「削除しても構わない」です。

`/usr/obj` には、 コンパイルの段階で生成された すべてのオブジェクトファイルが含まれています。 通常 `make buildworld` の最初の段階では、 このディレクトリを削除して新しくつくり直すようになっています。 構築終了後も `/usr/obj` を保存しておいても、あまり意味はありません。 削除すれば、だいたい 2 GB のディスクスペースを解放することができます。

良く理解をしているユーザであれば、 この段階を省略して `make buildworld` を行なうことができます。 こうすると、ほとんどのソースは再コンパイルされないため、 構築はかなり高速化されます。 これは裏をかえせば、デリケートな依存関係の問題によって、 システムの構築が奇妙な失敗に終わる可能性があるということです。 FreeBSD メーリングリストではしばしば、構築の失敗が、 この段階の省略によるものだということを理解せずに 不満の声をあげる人がいます。

18.7.16.4. | 構築を中断した場合、その構築を途中から再開することはできますか?

それは、問題が起こるまでに、 どれだけの作業を終えているかによって変わります。

一般的に `make buildworld` は、 gcc(1) や make(1) まどの基本的なツールや、 システムライブラリの新しいコピーを作成します。 その後、これらのツールやライブラリがインストールされてから、 自分自身の再構築に使われ、もう一度、インストールされます。 ls(1) や grep(1) といった標準的なユーザプログラムを含むシステム全体が、 その新しいシステムファイルを用いて作り直されます。

再構築の最終段階では、 まったく安全に次のようにすることができます。

… fix the problem … `#` `cd /usr/src` `#` `make -DNO_CLEAN all`

これは、前回の `make buildworld` の作業をやり直しません。

次のメッセージ

-------------------------------------------------------------- Building everything.. --------------------------------------------------------------

が `make buildworld` の出力にある場合には、 上のようにしてもほとんど悪影響が現れることはありません。

もしこのメッセージがないとか、よく分からないという場合には、 安全を確保し、後悔するようなことがないよう、 システムの再構築を最初からやり直しましょう。

18.7.16.5. | どのようにすれば make world を高速化できますか?

- シングルユーザモードで動かしてください。

- `/usr/src` と `/usr/obj` を、異なるディスク上の別のファイルシステムに置いてください。 また可能ならば、 異なるディスクコントローラに接続されたディスクを使ってください。

- さらに高速化するには、これらのファイルシステムを ccd(4) を使って、 複数のディスク上に置いてください。

- `/etc/make.conf` に 「NO_PROFILE=true」 をセットして、 プロファイル版の作成を無効化してください。

- make(1) に `-j`n`` を指定して、複数のプロセスを並列に実行させてください。 これは、単一のプロセッサでも複数のプロセッサでも、 同様に恩恵を得ることができます。

- `/usr/src` のあるファイルシステムを、`noatime` オプションを付けてマウントもしくは再マウントしてください。 これは、そのファイルシステムにおいて、 最後にアクセスされた時刻の書き込みを抑制します。 おそらく、この情報が必要になることはないでしょう。

  `#` `mount -u -o noatime /usr/src`

  ### 警告:

  上の例は、 `/usr/src` 自身が独立したファイルシステムであることを想定しています。 もし `/usr` の一部である場合には、 かわりに適切なマウントポイントを指定すしてください。

- `/usr/obj` のあるファイルシステムを、`async` オプションをつけてマウントもしくは再マウントしてください。 これによって、ディスクへの書き込みが非同期になります。 つまり、書き込み命令はすぐに完了するのに対し、 実際にデータがディスクに書き込まれるのは、その数秒後になります。 これによって、書き込み処理の一括化が可能になるため、 劇的なパフォーマンスの向上が期待できます。

  ### 警告:

  このオプションを指定すると、ファイルシステムは 壊れやすくなってしまうことに注意してください。 このオプションを付けていて、突然電源が落ちた場合には、 再起動後にファイルシステムが復旧不能になる可能性が 非常に高くなります。

  もし、`>/usr/obj` が、ファイルシステムにある唯一のディレクトリであれば、 これは問題になりません。 しかし、同じファイルシステムに、他の貴重なデータを置いているときには、 このオプションを有効にする前に、 バックアップをきちんと取っておきましょう。

  `#` `mount -u -o async /usr/obj`

  ### 警告:

  もし `/usr/obj` 自身がファイルシステムでない場合には、 適切なマウントポイントを指すように、 上の例の名前を置き換えてください。

18.7.16.6. | なにか悪いことがあったらどうすればいいですか?
| 自分の環境に前のビルドの余計なゴミが残っていないことをはっきりと確認してください。 `#` `chflags -R noschg /usr/obj/usr` `#` `rm -rf /usr/obj/usr` `#` `cd /usr/src` `#` `make cleandir` `#` `make cleandir` ええ、`make cleandir` は本当に 2 回実行するのです。 そして、`make buildworld` を行い、 全プロセスを最初からやり直してください。 まだ問題があれば、エラーと `uname -a` の出力を FreeBSD general questions メーリングリスト に送ってください。 設定についてさらに質問されても答えられるよう用意してください!

戻る | 上に戻る | 次へ
18.6. ソースの同期 | ホーム | 18.8. 複数のマシンで追いかける

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

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