以下のような場合、FreeBSD をアップグレードすることは簡単ではないはずです。
- Raspberry Pi のように freebsd-update でサポートされない Tier 2 プラットフォーム
- なおかつ、リモート環境など、 OS がインストールされている micro SD カードなどを物理的に扱うことができない環境
- buildworld しようにもメモリもディスクも容量が足りない環境
このような場合、最近では別環境でビルドしたベースパッケージを使ってアップグレードをするという方法があります。
前提
amd64, Raspberry Piの各モデル向けに各OSトレインのベースパッケージを作成する。
ビルドマシン
- AMD64
- 8vCPU
- 8GB程度のメモリ
- 200GB以上の高速なディスク
- FreeBSD 12.2-RELEASE
所要時間の目安として、一つのOSトレイン一つのアーキテクチャ向けベースパッケージを作成すると当方の環境では30分弱程度かかりました。
ソースツリーのアップデート
/usr/local/bin/update-src.sh(subversion)
#!/bin/sh if [ -x /usr/bin/svnlite ]; then SVN=svnlite else SVN=svn fi #$SVN checkout https://svn.FreeBSD.org/base/releng/12.2 /usr/src-releng #$SVN checkout https://svn.FreeBSD.org/base/stable/12 /usr/src-stable #$SVN checkout https://svn.FreeBSD.org/base/head /usr/src-current $SVN update /usr/src-releng $SVN update /usr/src-stable $SVN update /usr/src-current
/usr/local/bin/update-src.sh(git)
#!/bin/sh #git clone -o upstream -b main https://git.freebsd.org/src.git #git clone https://git.freebsd.org/src.git ssh://anongit@git.freebsd.org/src.git #git clone https://git.freebsd.org/src.git /usr/src #git clone -b releng/13.0 --depth 1 https://git.freebsd.org/src.git /usr/src-releng #git clone -b stable/13 --depth 1 https://git.freebsd.org/src.git /usr/src-stable cd /usr/src-stable git config pull.ff only git branch -v git pull cd /usr/src-releng git config pull.ff only git branch -v git pull cd /root #git remote -v
アーキテクチャごとのビルド
/usr/local/bin/makeworld.sh
#!/bin/sh if [ $# -lt 1 ]; then echo "$0 [current|stable|releng] [amd64|armv6|armv7|aarch64]" exit 255 fi TRAIN="$1" ARCH="amd64" if [ $# -gt 1 ]; then ARCH="$2" fi MAKE="make -j 8" WORLDLOG="buildworld-${ARCH}.log" KERNELLOG="buildkernel-${ARCH}.log" PACKAGESLOG="packages-${ARCH}.log" MADEPACKAGES="packages" case "${TRAIN}" in "current"|"stable"|"releng") cd /usr/src-${TRAIN} case "${ARCH}" in "armv6"|"rpi") ${MAKE} buildworld TARGET=arm TARGET_ARCH=armv6 UBLDR_LOADADDR=0x2000000 > ${WORLDLOG} 2>&1 && \ ${MAKE} buildkernel TARGET=arm TARGET_ARCH=armv6 KERNCONF=RPI-B > ${KERNELLOG} 2>&1 && \ ${MAKE} ${MADEPACKAGES} TARGET=arm TARGET_ARCH=armv6 KERNCONF=RPI-B > ${PACKAGESLOG} 2>&1 ;; "armv7"|"rpi2") if [ -f sys/arm/conf/RPI2 ]; then ${MAKE} buildworld TARGET=arm TARGET_ARCH=armv7 UBLDR_LOADADDR=0x2000000 > ${WORLDLOG} 2>&1 && \ ${MAKE} buildkernel TARGET=arm TARGET_ARCH=armv7 KERNCONF=RPI2 > ${KERNELLOG} 2>&1 && \ ${MAKE} ${MADEPACKAGES} TARGET=arm TARGET_ARCH=armv7 KERNCONF=RPI2 > ${PACKAGESLOG} 2>&1 else ${MAKE} buildworld TARGET=arm TARGET_ARCH=armv7 UBLDR_LOADADDR=0x2000000 > ${WORLDLOG} 2>&1 && \ ${MAKE} buildkernel TARGET=arm TARGET_ARCH=armv7 > ${KERNELLOG} 2>&1 && \ ${MAKE} ${MADEPACKAGES} TARGET=arm TARGET_ARCH=armv7 > ${PACKAGESLOG} 2>&1 fi ;; "aarch64"|"armv8"|"rpi3") ${MAKE} buildworld TARGET=arm64 TARGET_ARCH=aarch64 > ${WORLDLOG} 2>&1 && \ ${MAKE} buildkernel TARGET=arm64 TARGET_ARCH=aarch64 > ${KERNELLOG} 2>&1 && \ ${MAKE} ${MADEPACKAGES} TARGET=arm64 TARGET_ARCH=aarch64 > ${PACKAGESLOG} 2>&1 ;; *) ${MAKE} buildworld > ${WORLDLOG} 2>&1 && \ ${MAKE} buildkernel > ${KERNELLOG} 2>&1 && \ ${MAKE} ${MADEPACKAGES} > ${PACKAGESLOG} 2>&1 ;; esac ;; *) ;; esac
すべてのアーキテクチャのビルド
/usr/local/bin/makeworld-all.sh
#!/bin/sh ARCHITECTURE="amd64 armv6 armv7 aarch64" RELS="releng stable current" for rel in ${RELS} do chflags -R noschg /usr/obj/usr/src-$rel rm -rf /usr/obj/usr/src-$rel for arch in ${ARCHITECTURE} do /usr/local/bin/makeworld.sh $rel $arch done done
アップグレード
ローカルアップグレード設定
/usr/local/etc/pkg/repos/FreeBSD-base.conf
FreeBSD-base: { file: "/usr/obj/usr/src-stable/repo/${ABI}/latest", mirror_type: "none", enabled: yes }
リモートアップグレード設定
ビルドしたベースパッケージを HTTP サーバーでアクセスできるようにしておき、そのパッケージサーバーからパッケージを取得します。
/usr/local/etc/apache24/Includes/freebsd-base.conf
Alias /repo "/usr/obj/usr/src-stable/repo" <Directory "/usr/obj/usr/src-stable/repo"> Options Indexes FollowSymLinks AllowOverride None Require local Require ip 192.168.0.0/16 </Directory>
/usr/local/etc/pkg/repos/FreeBSD-base.conf
FreeBSD-base: { url: "http://pkg.example.com/repo/${ABI}/latest", enabled: yes }
ベースパッケージの初期化
rsync -av /etc/ /etc.old/ pkg update -r FreeBSD-base pkg install -y -r FreeBSD-base -g 'FreeBSD-*' rm -rf /etc rsync -av /etc.old/ /etc/
アップグレード
マイナーアップグレードの実行
既存パッケージのアップグレードと、追加パッケージのインストールを行います。
mergemaster -p pkg update -r FreeBSD-base pkg upgrade -y -r FreeBSD-base pkg install -y -r FreeBSD-base -g 'FreeBSD-*' reboot mergemaster
メジャーアップグレードの実行
FreeBSD 11 から 12 のようにメジャーバージョンをアップグレードするときは明示的に ABI を指定します。また、ライブラリ関係の問題を避けるためにpkg-staticを使います。また、不要になった古いパッケージを削除します。
mergemaster -p rsync -av /etc/ /etc.old/ env ABI=FreeBSD:12:amd64 IGNORE_OSVERSION=yes pkg upgrade -y -r FreeBSD-base env ABI=FreeBSD:12:amd64 IGNORE_OSVERSION=yes pkg-static install -y -r FreeBSD-base -g 'FreeBSD-*' pkg remove -y 'FreeBSD-*-11*' rm -rf /etc mv /etc.old /etc reboot mergemaster pkg-static upgrade -y -r FreeBSD pkg pkg update -r FreeBSD pkg upgrade -y -r FreeBSD
保存されたファイルを削除します。
find / -name "*.pkgsave" -print | xargs rm -f find / -name "*.pkgnew" -print | xargs rm -f
CURRENTのアップグレード
CURRENTからCURRENTへアップグレードするときはライブラリ関係の問題を避けるためにpkg-staticを使います。また、不要になった古いパッケージを削除します。
また、open-vm-toolsを動かしている場合は、カーネルモジュールが動作しなくなる可能性があるので一時的に削除して、アップグレードが終わったら再度インストールするようにします。
mergemaster -p rsync -av /etc/ /etc.old/ pkg-static install -y -r FreeBSD-base -g 'FreeBSD-*' pkg-static remove -y 'FreeBSD-*-14.snap2021*' pkg remove -y open-vm-tools rm -rf /etc mv /etc.old /etc reboot mergemaster pkg update -r FreeBSD pkg upgrade -y -r FreeBSD pkg install -y -r FreeBSD open-vm-tools