FreeBSD 12のアップデート

おうちサーバといえども、一応OSのアップデートを行って、最新版にしておきましょう。
FreeBSDのOSのアップデート方法はいくつかありますが、せっかくなので、もっとも手間のかかるソースプログラムを用いたアップデートを行いましょう。

  • ソースコードをアップデートする
  • ユーザランドのコンパイル
  • カーネルのコンパイル&インストール
  • 再起動
  • ユーザーランドのインストール
  • 設定ファイルのチェック
  • 再起動

という手順で行います。

ソースコードをアップデートする

一番最初に、ソースコードをアップデートするとき、何に同期させるかを指定しましょう。
参考 表17.1「FreeBSD のバージョンおよびリポジトリパス」
STABLEやCURRENTを追いかけるのも魅力的ですが、今回は、

root@cafe:~ # uname -r
12.1-RELEASE
root@cafe:~ #

より12.1-RELEASEに同期させることにします。

root@cafe:~ # svnlite checkout https://svn.freebsd.org/base/releng/12.1 /usr/src
Error validating server certificate for 'https://svn.freebsd.org:443':
 - The certificate is not issued by a trusted authority. Use the
   fingerprint to validate the certificate manually!
Certificate information:
 - Hostname: svn.freebsd.org
 - Valid: from Aug 18 20:30:53 2020 GMT until Nov 16 20:30:53 2020 GMT
 - Issuer: Let's Encrypt Authority X3, Let's Encrypt, US
 - Fingerprint: 0F:6B:97:A0:9A:13:E5:F7:C2:64:FE:84:45:BF:9A:CD:9E:3F:C6:35
(R)eject, accept (t)emporarily or accept (p)ermanently? p
   C /usr/src/.arcconfig
   C /usr/src/.arclint
   C /usr/src/.gitattributes
   C /usr/src/.gitignore
:
省略
:
   A /usr/src/usr.sbin/zzz/zzz.8
   A /usr/src/usr.sbin/ypserv/ypserv.8
   A /usr/src/usr.sbin/ypset/ypset.c
   A /usr/src/usr.sbin/zic/zdump/Makefile
   A /usr/src/usr.sbin/zonectl/Makefile
   A /usr/src/usr.sbin/zzz/Makefile
   A /usr/src/usr.sbin/zonectl/zonectl.c
   A /usr/src/usr.sbin/zzz/zzz.sh
 U   /usr/src
Checked out revision 366115.
root@cafe:~ #

初回はちょっと時間がかかりますね。
初めて、svn.freebsd.orgに接続するとき、確認を求められるので、accept (p)ermanentlyとしてpを入力します。

ちゃんと同期が取れているか確認してみましょう。

root@cafe:~ # svnlite info /usr/src
Path: /usr/src
Working Copy Root Path: /usr/src
URL: https://svn.freebsd.org/base/releng/12.1
Relative URL: ^/releng/12.1
Repository Root: https://svn.freebsd.org/base
Repository UUID: ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f
Revision: 366115
Node Kind: directory
Schedule: normal
Last Changed Author: gordon
Last Changed Rev: 365782
Last Changed Date: 2020-09-16 06:48:24 +0900 (Wed, 16 Sep 2020)

root@cafe:~ #

https://svn.freebsd.org/base/releng/12.1と同期が取れていることが確認できました!

2回目からは

root@cafe:~ # svnlite update /usr/src
Updating '/usr/src':
At revision 366116.
root@cafe:~ #

svnlite update /usr/srcコマンドだけでOKです。

ユーザランドのコンパイル

次は、ユーザランドのコンパイルです。今回はVirtualBoxの仮想マシンとして1CPUなのでmake buildworldコマンドをつかます。
複数CPUがある場合はmake -j4 buildworld(CPUが4つの場合)にすれば速くなりますよ!

root@cafe:~ # cd /usr/src
root@cafe:/usr/src # make buildworld
[Creating objdir /usr/obj/usr/src/amd64.amd64...]
make[1]: "/usr/src/Makefile.inc1" line 341: SYSTEM_COMPILER: Determined that CC=cc matches the source tree.  Not bootstrapping a cross-compiler.
make[1]: "/usr/src/Makefile.inc1" line 346: SYSTEM_LINKER: Determined that LD=ld matches the source tree.  Not bootstrapping a cross-linker.
--------------------------------------------------------------
>>> World build started on Fri Sep 25 00:07:33 JST 2020
--------------------------------------------------------------

--------------------------------------------------------------
>>> Rebuilding the temporary build tree
--------------------------------------------------------------
rm -rf /usr/obj/usr/src/amd64.amd64/tmp
cd /usr/src/tools/build;  make DIRPRFX=tools/build/ DESTDIR=/usr/obj/usr/src/amd
:
省略
:
nused-parameter -Wstrict-prototypes -Wmissing-prototypes -Wpointer-arith -Wreturn-type -Wcast-qual -Wwrite-strings -Wswitch -Wshadow -Wunused-parameter -Wcast-align -Wchar-subscripts -Winline -Wnested-externs -Wredundant-decls -Wold-style-definition -Wno-pointer-sign -Wmissing-variable-declarations -Wthread-safety -Wno-empty-body -Wno-string-plus-int -Wno-unused-const-variable -Qunused-arguments   -o ldd32.full ldd.o sods.o
objcopy --only-keep-debug ldd32.full ldd32.debug
objcopy --strip-debug --add-gnu-debuglink=ldd32.debug  ldd32.full ldd32

--------------------------------------------------------------
>>> World build completed on Fri Sep 25 04:26:36 JST 2020
--------------------------------------------------------------
You have new mail.
root@cafe:/usr/src #

こちらの環境では、4時間以上かかりましたね。

カーネルのコンパイル&インストール&再起動

make kernelコマンドでカーネルのコンパイルとインストールを行います。
こちらも、複数CPUがある場合はmake -j4 kernel(CPUが4つの場合)にすれば速くなります。
以前はメモリを節約するために不要なドライバを削除してカスタムカーネルを作っていましたが、最近のFreeBSDのカーネルはドライバを動的に組み込むので、ドライバがたくさん入っていてもメモリを圧迫しません。
よって、ここではGENERICカーネルのままにしておきます。

root@cafe:/usr/src # make kernel
make[1]: "/usr/src/Makefile.inc1" line 341: SYSTEM_COMPILER: Determined that CC=cc matches the source tree.  Not bootstrapping a cross-compiler.
make[1]: "/usr/src/Makefile.inc1" line 346: SYSTEM_LINKER: Determined that LD=ld matches the source tree.  Not bootstrapping a cross-linker.

--------------------------------------------------------------
>>> Kernel build for GENERIC started on Sat Sep 26 00:21:52 JST 2020
--------------------------------------------------------------
===> GENERIC
mkdir -p /usr/obj/usr/src/amd64.amd64/sys

--------------------------------------------------------------
>>> stage 1: configuring the kernel
--------------------------------------------------------------
:
省略
:
===> xz (install)
install -T release -o root -g wheel -m 555   xz.ko /boot/kernel/
install -T debug -o root -g wheel -m 555   xz.ko.debug /usr/lib/debug/boot/kernel/
===> zfs (install)
install -T release -o root -g wheel -m 555   zfs.ko /boot/kernel/
install -T debug -o root -g wheel -m 555   zfs.ko.debug /usr/lib/debug/boot/kernel/
===> zlib (install)
install -T release -o root -g wheel -m 555   zlib.ko /boot/kernel/
install -T debug -o root -g wheel -m 555   zlib.ko.debug /usr/lib/debug/boot/kernel/
kldxref /boot/kernel
--------------------------------------------------------------
>>> Installing kernel GENERIC completed on Sat Sep 26 00:49:59 JST 2020
--------------------------------------------------------------
root@cafe:/usr/src #

続いて、リブートを行い新しいカーネルを読み込ませます。

root@cafe:/usr/src # shutdown -r now

再ログイン後、dmesgコマンドでカーネルが新しくなったことを確認します。

root@cafe:~ # dmesg
---<<BOOT>>---
Copyright (c) 1992-2019 The FreeBSD Project.
Copyright (c) 1979, 1980, 1983, 1986, 1988, 1989, 1991, 1992, 1993, 1994
        The Regents of the University of California. All rights reserved.
FreeBSD is a registered trademark of The FreeBSD Foundation.
FreeBSD 12.1-RELEASE #0 r366116M: Sat Sep 26 00:31:30 JST 2020
    root@cafe.lo.zeke.ne.jp:/usr/obj/usr/src/amd64.amd64/sys/GENERIC amd64
FreeBSD clang version 8.0.1 (tags/RELEASE_801/final 366581) (based on LLVM 8.0.1)
VT(vga): text 80x25
:
省略
:

ユーザーランドのインストール

次にmake installworldコマンドで、ユーザーランドのインストールを行います。

root@cafe:~ # cd /usr/src/
root@cafe:/usr/src # make installworld
make[1]: "/usr/obj/usr/src/amd64.amd64/toolchain-metadata.mk" line 1: Using cached toolchain metadata from build at cafe.lo.zeke.ne.jp on Fri Sep 25 00:15:00 JST 2020
--------------------------------------------------------------
>>> Install check world
--------------------------------------------------------------
:
省略
:
install  -s -o root -g wheel -m 555   ldd32 /usr/bin/ldd32
install  -o root -g wheel -m 444  ldd32.debug /usr/lib/debug/usr/bin/ldd32.debug
--------------------------------------------------------------
>>> Installing everything completed on Sat Sep 26 01:08:04 JST 2020
--------------------------------------------------------------
root@cafe:/usr/src #

こちらの入れ替えもできました!

設定ファイルのチェック&再起動

ユーザーランドの入れ替えで、/etc/の下の設定ファイルも入れ替わっています。それをカスタムした内容を反映しなくてはいけません。
mergemaster -Uiコマンドを使うと、設定ファイルが新しくなったかどうかチェックし、古い設定ファイルがカスタマイズされていたらその内容を反映させるか聞いてくれます。
基本的にマイナーバージョンでは設定ファイルが新しくなることはありません。
12.1から12.2にバージョンアップしたときに、変わることもあるので、そのとき便利なコマンドです。

root@cafe:/usr/src # mergemaster -Ui

*** Creating the temporary root environment in /var/tmp/temproot
 *** /var/tmp/temproot ready for use
 *** Creating and populating directory structure in /var/tmp/temproot
 :
 省略
 :
  *** Temp ./etc/master.passwd and installed have the same Id, deleting

   ======================================================================

  *** Displaying differences between ./etc/motd and installed version:

--- /etc/motd   2020-09-26 00:51:44.927801000 +0900
+++ ./etc/motd  2020-09-26 01:15:41.816260000 +0900
@@ -1,4 +1,4 @@
-FreeBSD 12.1-RELEASE (GENERIC) #0 r366116M: Sat Sep 26 00:31:30 JST 2020
+FreeBSD ?.?.?  (UNKNOWN)

 Welcome to FreeBSD!

(END)

/etc/motdが変わってますね。moreからqキーを押して、抜けます。

  Use 'd' to delete the temporary ./etc/motd
  Use 'i' to install the temporary ./etc/motd
  Use 'm' to merge the temporary and installed versions
  Use 'v' to view the diff results again

  Default is to leave the temporary file to deal with by hand

How should I deal with this? [Leave it for later]

元の内容を残したいのでdキーで新しい/etc/motdを削除しても良いのですが、ここはmキーでマージしてみます。

How should I deal with this? [Leave it for later] m

FreeBSD 12.1-RELEASE (GENERIC) #0 r366 | FreeBSD ?.?.?  (UNKNOWN)
%?
e:      edit blank diff
eb:     edit both diffs concatenated
el:     edit left diff
er:     edit right diff
l | 1:  choose left diff
r | 2:  choose right diff
s:      silent mode--don't print identical lines
v:      verbose mode--print identical lines
q:      quit
%

mキーを押すと、違っているところを表示し、どちらを採用するか選択画面が出ます。?キーでヘルプ画面を出してみました。
編集もできますが、lキーで左、rキーで右を選択するのが簡単です。今回はlキーで左ですね。

%l

  Use 'i' to install merged file
  Use 'r' to re-do the merge
  Use 'v' to view the merged file
  Default is to leave the temporary file to deal with by hand

    *** How should I deal with the merged file? [Leave it for later]

確認画面が出るので、iキーでインストール実行です。

*** Comparison complete
*** Saving mtree database for future upgrades

*** /var/tmp/temproot is empty, deleting

*** Reinstalling Asia/Tokyo as /etc/localtime

root@cafe:/usr/src #

変わっていたのは、/etc/motdだけだったので、これで完了です。

root@cafe:/usr/src # shutdown -r now

再び再起動を行います。

root@cafe:~ # ls -l /bin
total 2288
-r-xr-xr-x  2 root  wheel   23672 Sep 26 01:04 [
-r-xr-xr-x  1 root  wheel   23672 Sep 26 01:04 cat
-r-xr-xr-x  1 root  wheel   15400 Sep 26 01:04 chflags
-r-xr-xr-x  1 root  wheel   27672 Sep 26 01:04 chio
-r-xr-xr-x  1 root  wheel   19488 Sep 26 01:04 chmod
-r-xr-xr-x  1 root  wheel   27744 Sep 26 01:04 cp
-r-xr-xr-x  2 root  wheel  433232 Sep 26 01:04 csh
-r-xr-xr-x  1 root  wheel   36104 Sep 26 01:04 date
-r-xr-xr-x  1 root  wheel   36344 Sep 26 01:04 dd
-r-xr-xr-x  1 root  wheel   27864 Sep 26 01:04 df
-r-xr-xr-x  1 root  wheel   15408 Sep 26 01:04 domainname
-r-xr-xr-x  1 root  wheel   15392 Sep 26 01:04 echo
-r-xr-xr-x  2 root  wheel   65136 Sep 26 01:04 ed
-r-xr-xr-x  1 root  wheel   27696 Sep 26 01:04 expr
-r-xr-xr-x  1 root  wheel    3412 Sep 26 01:04 freebsd-version
-r-xr-xr-x  1 root  wheel   19496 Sep 26 01:04 getfacl
-r-xr-xr-x  1 root  wheel   15400 Sep 26 01:04 hostname
-r-xr-xr-x  1 root  wheel   15392 Sep 26 01:04 kenv
-r-xr-xr-x  1 root  wheel   15552 Sep 26 01:04 kill
-r-xr-xr-x  2 root  wheel   19480 Sep 26 01:04 link
-r-xr-xr-x  2 root  wheel   19480 Sep 26 01:04 ln
-r-xr-xr-x  1 root  wheel   40304 Sep 26 01:04 ls
-r-xr-xr-x  1 root  wheel   15392 Sep 26 01:04 mkdir
-r-xr-xr-x  1 root  wheel   23576 Sep 26 01:04 mv
-r-xr-xr-x  1 root  wheel  110704 Sep 26 01:04 pax
-r-xr-xr-x  2 root  wheel   23784 Sep 26 01:04 pgrep
-r-xr-xr-x  2 root  wheel   23784 Sep 26 01:04 pkill
-r-xr-xr-x  1 root  wheel   52696 Sep 26 01:04 ps
-r-xr-xr-x  1 root  wheel   15392 Sep 26 01:04 pwait
-r-xr-xr-x  1 root  wheel   15384 Sep 26 01:04 pwd
-r-xr-xr-x  1 root  wheel   15400 Sep 26 01:04 realpath
-r-xr-xr-x  2 root  wheel   65136 Sep 26 01:04 red
-r-xr-xr-x  2 root  wheel   23576 Sep 26 01:04 rm
-r-xr-xr-x  1 root  wheel   80944 Sep 26 01:04 rmail
-r-xr-xr-x  1 root  wheel   15392 Sep 26 01:04 rmdir
-r-xr-xr-x  1 root  wheel   32176 Sep 26 01:04 setfacl
-r-xr-xr-x  1 root  wheel  168968 Sep 26 01:04 sh
-r-xr-xr-x  1 root  wheel   15392 Sep 26 01:04 sleep
-r-xr-xr-x  1 root  wheel   32296 Sep 26 01:04 stty
-r-xr-xr-x  1 root  wheel   15264 Sep 26 01:04 sync
-r-xr-xr-x  2 root  wheel  433232 Sep 26 01:04 tcsh
-r-xr-xr-x  2 root  wheel   23672 Sep 26 01:04 test
-r-xr-xr-x  2 root  wheel   23576 Sep 26 01:04 unlink
-r-xr-xr-x  1 root  wheel   15400 Sep 26 01:04 uuidgen
root@cafe:~ #

ログイン後、/bin内のファイルスタンプを確認し、インストールした日付になっていることを確認しました。

使わなくなったファイルやライブラリの削除

最後にアップデートで使わなくなったファイルやライブラリを削除します。

root@cafe:~ # cd /usr/src/
root@cafe:/usr/src # make check-old
>>> Checking for old files
>>> Checking for old libraries
>>> Checking for old directories
To remove old files and directories run 'make delete-old'.
To remove old libraries run 'make delete-old-libs'.
root@cafe:/usr/src # make delete-old
>>> Removing old files (only deletes safe to delete libs)
>>> Old files removed
>>> Removing old directories
>>> Old directories removed
To remove old libraries run 'make delete-old-libs'.
root@cafe:/usr/src # make delete-old-libs
>>> Removing old libraries
Please be sure no application still uses those libraries, else you
can not start such an application. Consult UPDATING for more
information regarding how to cope with the removal/revision bump
of a specific library.
>>> Old libraries removed
root@cafe:/usr/src #

/usr/src/の下でmake check-oldコマンドを実施します。
その後、出てくるメッセージのとおり、make delete-oldが古いファイルの削除、make delete-old-libsが古いライブラリの削除コマンドになります。

これでOSのアップデートは完了です。