FreeBSDをソースコードでアップグレード

2023年4月11日、FreeBSD 13.2-RELEASEが公開されました。
稼働しているFreeBSDのバージョンは13.1-RELEASE-p7。13.2-RELEASE発表後、13.1系は3ヶ月で保守終了になりますので、早々とアップグレードする必要があります。

ソースコードでアップグレードする方法については、本家サイトのハンドブックで丁寧に説明されていますが、実践した内容を紹介します。

バージョンは13.1-RELEASE-p7から13.2-RELEASEです。

手順

ソースコードでアップグレードするためには、ハンドブックによると以下のようになります。

# git pull /usr/src
check /usr/src/UPDATING.
# cd /usr/src
# make -j4 buildworld
# make -j4 kernel
# shutdown -r now
# etcupdate -p
# cd /usr/src
# make installworld
# etcupdate -B
# shutdown -r now

ハンドブックによれば、ソースコードをgitで取得していますが、このページではportsのgitupコマンドを使用します。

1. gitupでソースを取得する

すでにソースを取得している方はこの節は飛ばしていただいて構いません。

FreeBSDのソースコードを取得するにはgitを使用する方法が一般的ですが、私はportsにあるgitupを使用します。gitの使い方がわからなくてもソースコードを簡単に取得できますのでオススメです。

# cd /usr/ports/net/gitup
# make
# make install
# make clean

/usr/local/etcディレクトリにgitup.confファイルがコピーされているので、これをテキストエディタで編集します。
“release”で始まるブロックを見つけます。“branch”の項目を“releng/13.2”に書き換えます。

        "release" : {
                "repository_path"  : "/src.git",
                "branch"           : "releng/13.2",
                "target_directory" : "/usr/src",
                "ignores"          : [
                        "sys/amd64/conf",
                        "sys/arm64/conf",
                        "sys/i386/conf",
                        "sys/pc98/conf",
                        "sys/powerpc/conf",
                        "sys/riscv/conf",
                        "sys/sparc64/conf",
                ]
        },

あとは以下のコマンドを実行すればソースが取得できます。

# gitup release

現状 /usr/src にあるソースコード(ここでは13.1-RELEASE-p7)をチェックして新たなソースコード(13.2-RELEASE)を取得しはじめます。
/usr/src/UPDATINGの確認を促すメッセージが表示され、最後に“Done.”が表示されれば、正常に完了します。

# Scanning local repository...
# Host: git.freebsd.org
# Port: 443
# Repository Path: /src.git
# Target Directory: /usr/src
# Have: d7fd13df4e84673bcdc3c17fd1e49e7842dbe3e3
# Want: fc952ac2212b121aa45258273f5960ec3e0a466d
# Branch: releng/13.2
  15 MB in 0m06s, 7211 kB/s now 
・
・
・
#
# Please review the following file(s) for important changes.
#	/usr/src/UPDATING
#
# Done.

これでソースコードを取得することができました。

2. /usr/src/UPDATINGファイルの確認

前節のソースコード取得時に最後に言われた通り、/usr/src/UPDATINGファイルで変更内容を確認しましょう。

セキュリティの脆弱性などのパッチの場合は、詳細やmake world,make kernelなどどこまで影響があるか記述されていることがあるので、必ず確認しましょう。

2.5. make buildworldの前にすること

etcupdateを初めて実行する際は、衝突を回避するために以下をbuildworldを行う前に実行しないといけないようです。

# etcupdate extract

以下を実行すると、差分を確認することができます。

# etcupdate diff

3~4. make buildworldする

最初にworldを再構築します。
ちなみに、FreeBSDにおける“world”とはFreeBSDのドキュメントによると以下のことになります。

FreeBSD では、「world」 は、 カーネル、コアシステムのバイナリ、 ライブラリ、プログラミングファイル、組み込みのコンパイラを意味します。 これらのコンポーネントの構築およびインストールの順番は重要です。

https://docs.freebsd.org/doc/10.3-RELEASE/usr/local/share/doc/freebsd/ja/books/handbook/makeworld.html

※必ずバックアップして起動メディア(USBメモリやDVD)を作成し、不測の事態に備えてください。万が一トラブルが発生しても責任を取ることはできません。自己責任でお願いします。

前準備

コンパイルを開始する前に/usr/objディレクトリを削除します。ディレクトリが存在しなければこの節は跳ばしていただいて構いません。
このディレクトリは、コンパイラーが出力する.objファイルなどの中間ファイルや目的の実行ファイル、ライブラリなどを保管するディレクトリです。再度構築する際に変更されていないソースコードのコンパイルやリンクを省略し、時間短縮を図るために存在します。
ただし、アップグレードなどでソースコードの変更量が大きい場合は、依存するライブラリのバージョンの違いなどによって訳のわからないエラーが発生したりするため、すべてのソースコードのコンパイルやリンクをしてもらえるよう、/usr/obj ディレクトリを削除します。

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

ビルド

以下のコマンドを実行します。

# make -j4 buildworld

-jオプションはマルチプロセッサやマルチコアに有用なオプションで、指定すると並列で処理を実行し、時間短縮を図ることができます。数値で並列数の指定ができます。コア数が多ければ大きめな値を指定しても良いかもしれません。
私の環境の場合は、経験的に4が一番効率的だと思っています。複数のソースファイルのコンパイル・リンクが複数同時に実行されますが、結局のところ、ストレージが関係するので大きな値を指定しても速くなったようには感じられません。
ちなみに、当方の環境は、CPUは第6世代Core i5(論理プロセッサ数=4)、メモリは16GB、256GB SSDです。

プロンプトが返ってくるまでに2時間程度かかりました。

5. カーネルのビルド・インストール

次にカーネルの再構築を行います。

当方の環境では、プロバイダとの接続にPPPoEが必要であったり、ファイアウォールを使用するのでカスタムカーネルを使用しています。

ハンドブックでは、“make kernel”と一発でビルドとインストールを行っていますが、-j4 オプションを使いたいことと、ビルドでエラーが発生していないことを確認してからインストールしたいため、私は別々に分けて実行します。

ちょっと寄り道

カスタムカーネルを作成するには『カーネルコンフィグレーションファイル』を作成する必要があります。
このファイルは、カーネルに含めるデバイスドライバを選択してカーネルのサイズを小さくしたり、GENERICカーネルに含まれていない機能を組み込んだりすることができます。

私は最近まで、GENERICファイルをコピーし、identを変更し、PPPoE、ipfwなどを組み込む記述をしていました。
ただ、OSのメジャーアップグレードなどを行うと、廃止になったドライバなどでエラーが発生したりするため、毎回GENERICをコピーしては書き換えていました。結構面倒でした。

ところが、どのサイトか覚えていませんが、“include”が使えることを知りました。
こんな便利なものがあったなんて・・・

何が便利か。要するに追加したり変更したりしたい差分のみを自分のカスタムカーネルの内容を書いておき、残りはGENERICと同じだよ・・・としておけるのです。
これであれば、毎回GENERICをコピーして編集する必要もなくなりました。

include         GENERIC

ident           TCS       ← GENERICに置き換えられる名前(識別子)

# Firewall
options         IPFIREWALL
options         IPFIREWALL_VERBOSE
options         IPFIREWALL_VERBOSE_LIMIT=3000

# PPPoE
options         DUMMYNET
options         NETGRAPH
options         NETGRAPH_ETHER
options         NETGRAPH_PPPOE
options         NETGRAPH_SOCKET
options         IPDIVERT

1行目のinclude・・・が肝です。あとはIPFirewall、PPPoEの機能を使用するための差分を書いておけば、OSがバージョンアップしても何も変更がいりません。(もちろん、これらの機能が廃止されたら変更が必要ですが。)

そしてこれをホームディレクトリに配置して、/usr/src/sys/amd64/conf/ (Intel系64ビットの場合)ディレクトリにリンクを作成しておけばOKです。

 ln -s ~/TCS /usr/src/sys/amd64/conf/

カーネルのビルド

話を戻します。

前節のようなカスタムカーネルを構築する場合は以下のようにします。

# make -j4 buildkernel KERNCONF=(カーネルコンフィグレーションファイル名)

「カーネルコンフィグレーションファイル名」は前節ように作成したファイル名を指定します。このファイルにパスは書けません。/usr/src/sys/amd64/conf ディレクトリにあるファイル名を指定します。
私の環境の場合は以下のようになります。

# make -j4 buildkernel KERNCONF=TCS

『TCS』は前節で解説したように、ホームディレクトリにTCSという名前でファイルを作成し、

# ln -s ~/TCS /usr/src/sys/amd64/conf/

でコンフィグレーションファイルがあるべき場所にリンクを作成したファイルです。

カーネルのコンパイルは私の環境で10分程度で完了します。

--------------------------------------------------------------
>>> Kernel build for TCS completed on Sun May 12 12:48:28 JST 2023
--------------------------------------------------------------
>>> Kernel(s)  TCS built in 428 seconds, ncpu: 4, make -j4
--------------------------------------------------------------

再コンパイルしてみただけなので、7分程度で完了してますね。

カーネルのインストール

ビルドがエラーなしに完了していることを確認したらインストールします。
※インストールに-j4オプションは指定してはいけません。

# make installkernel KERNCONF=TCS

カスタムカーネルの場合は、“KERNCONF=”でビルド時に指定したコンフィグレーションファイル名を指定します。

6. 再起動

カーネルのインストールが完了したらサーバを再起動します。

# shutdown -r now

7. etcupdate -p

installworldを成功させるためにファイルを一時的に変更します。詳しくはmanで確認してください。
/boot, /root, /usr/share, /etc, /usr/local/etc などのディレクトリが対象になるようです。

# etcupdate -p

8~9. worldのインストール

いよいよ終わりが見えてきました。ついにworldをインストールします。

環境によっては一晩かかったmake buildworldしたものを反映します。これには数分はかかります。

# make installworld

ここでもmake installkernelと同じく -j4 オプションを指定してはいけません。おそらくエラーになります。

10. etcupdate -B

以下を実行します。

# etcupdate -B

“make installworld”によって変更されたファイルの内、前々節で述べたディレクトリのファイルを以前使用していたものとマージされます。(多分・・・。ここは詳しくないので、気になる方は別サイトを確認してください。)

11. 再起動

これで再起動すれば完了です。

# shutdown -r now

再起動後に確認

再起動が完了したらログインして、以下のコマンドを実行してみてください。

$ uname -a
FreeBSD mail.computer-service.jp 13.2-RELEASE FreeBSD 13.2-RELEASE ********* TCS amd64

“13.2-RELEASE”と表示されています。アップグレードに成功したようです。
“TCS”はカーネルのビルド、インストール時に指定したKERNCONF=で指定したTCSが表示されています。カスタムカーネルで稼働していることがわかります。

戸塚

www.computer-service.jp

コンピュータ業界に30年近く身を置いていましたが、現在では建築関係、その他、まったくの異業種に。 コンピュータに関する『こまった』をサポートするべく事業を開始。