ソースの表示以前のリビジョンバックリンク全て展開する/折り畳む文書の先頭へ Share via Share via... Twitter LinkedIn Facebook Pinterest Telegram WhatsApp Yammer Reddit Teams最近の変更Send via e-Mail印刷パーマリンク × 目次 FreeBSDのいにしえのRoot on ZFSをBoot Environmentに変換する 試した環境 ファイルシステム構成の確認 手順 独自データセットの解消 Boot Environment環境にないデータセットの解消 旧Root on ZFS環境のマウントポイントの補正 Boot Environment環境の構築 起動データセットの変更 FreeBSDのいにしえのRoot on ZFSをBoot Environmentに変換する FreeBSD 11あたりで、Solaris由来のBoot Environmentという仕組みがシステムに取り込まれた。ZFSのスナップショットとクローンを使って、起動システムを簡単に複製したり切り替えたりするための仕組みで、OS更新時やカーネル関連の実験の時に有用である。 Boot Environmentを使うにはZFSのデータセットを、Boot Environment準拠の構造にする必要がある1)。bsdinstall以後のインストーラによるRoot on ZFS環境は、当然ながらBoot Environment準拠した構成となる。 大昔にRoot on ZFS環境を手動で作っている場合、例によってBoot Environment構成とは異なるため変換の必要がある。変換といっても、Boot Environmentなデータセットを作り、既存のファイルを全コピーで行けるハズ……ということでやってみた。 ちなみにBoot Environmentだろうとそうでなかろうと、システムの動作には一切影響しないので無理にBE化する必要もなかったりする。 試した環境 FreeBSD 12.2-RELEASE ファイルシステム構成の確認 FreeBSD 8時代のいにしえのRoot on ZFSなデータセット構成と、現在のBoot Environmentな構成を下表にまとめる。 従来のRoot on ZFS構成 Boot Environment構成 NAME mount point can mount comp- ression NAME mount point can mount comp- ression atime exec set uid zroot none on off zroot /zroot on lz4 (L) off (L) on on zroot/ROOT / on lz4 zroot/ROOT none on lz4 (i) off (i) on on zroot/ROOT/default / noauto (L) lz4 (i) off (i) on on zroot/ROOT/tmp /tmp on lz4 zroot/tmp /tmp on lz4 (i) off (i) on (L) off (L) zroot/ROOT/usr /usr on lz4 zroot/usr /usr off (L) lz4 (i) off (i) on on zroot/ROOT/usr/include /usr/include on gzip-9 (home用の別プールをマウント) /usr/home zroot/usr/home /usr/home on lz4 (i) off (i) on on zroot/ROOT/usr/ports /usr/ports on gzip-9 zroot/usr/ports /usr/ports on lz4 (i) off (i) on off (L) zroot/ROOT/usr/ports/distfiles /usr/ports/distfiles on off zroot/ROOT/usr/ports/packages /usr/ports/packages on off zroot/ROOT/usr/src /usr/src on gzip-9 zroot/usr/src /usr/src on lz4 (i) off (i) on on zroot/ROOT/var /var on off zroot/var /var off (L) lz4 (i) off (i) on on zroot/var/audit /var/audit on lz4 (i) off (i) off (L) off (L) zroot/ROOT/var/crash /var/crash on gzip-9 zroot/var/crash /var/crash on lz4 (i) off (i) off (L) off (L) zroot/ROOT/var/db /var/db on off zroot/ROOT/var/db/pkg /var/db/pkg on gzip-9 zroot/ROOT/var/empty /var/empty on off zroot/ROOT/var/log /var/log on gzip-9 zroot/var/log /var/log on lz4 (i) off (i) off (L) off (L) zroot/ROOT/var/mail /var/mail on gzip-9 zroot/var/mail /var/mail on lz4 (i) on (L) on on zroot/ROOT/var/run /var/run on off zroot/ROOT/var/tmp /var/tmp on off zroot/var/tmp /var/tmp on lz4 (i) off (i) on off (L) プロパティの凡例 (L) … SOURCEがlocal(自ファイルシステムで明示的に設定された値) (i) … SOURCEがinherited from … (親ファイルシステムから継承した値) 無印 … SOURCEがdefault “従来のRoot on ZFS構成”の方は省略 灰色の項目は当方の独自構成 いにしえ構成とBoot Environment構成のzroot/ROOTは名前が一緒なだけで、意味するところは明確に違うので混同に注意。前者は“ルートディレクトリのルート”、後者は“Boot Environmentでルートディレクトリ(/)となるデータセット置き場”のニュアンスである。 なお、いにしえ構成でROOTを噛ませているのは「トップレベルにデータセットを1つ作り、その下に他のデータセットを置くべし」という教えに従ったため。トップレベルに直接ファイルを置いたり、複数のファイルシステムがあると、スナップショットやzfs send/redvの取り扱いが少し面倒なため、こうした言い伝えがある。 今回のBoot Environemt化にあたっては、教えを無視して公式構成に準拠することとする。 Boot Environmentでは、zroot/ROOT以下に複数のシステム用データセットが格納でき、起動スプラッシュで選択した環境がファイルシステムの/となってシステムが起動する。標準のシステムはzroot/ROOT/defaultとなる。カーネル起動後、zroot/usrやzroot/tmpなどのzroot/ROOTと同列にあるデータセットがmountpointプロパティに従いマウントされることで、OSが想定するファイルシステム構造が出来上がるという仕掛けになっている。 注意すべきはcanmountプロパティがnoのデータセットたち。FreeBSD 12.2-RELEASE時点で該当するのは、zroot/usrとzroot/varである。 子データセットのcanmountはonなのに親がoffというのは一見不思議だが、なんて事はない、親は子供のための単なる“コンテナ”としての存在に過ぎない。逆に言うと、/usrの実体は各々のBoot Environmentに存在するため、zroot/usrがマウントされると都合が悪い。下表のように、同じ/usrでもパスによって格納先のデータセットが変わってくるため、移行作業では気を付ける必要がある。 ファイルパス ZFS的格納場所 /usr/bin/sh zroot/ROOT/defaultデータセット直下のusrディレクトリ内のbinディレクトリのshファイル /usr/ports/UPDATING zroot/usr/portsデータセット直下に配置されているUPDATINGファイル 以上をふまえ、下記の手順で移行を試みる。 独自データセットの解消 Boot Environment環境にないデータセットの解消 Boot Environment環境の構築 既存環境とBE環境を差し替える 要はzpoolのデータセット構成をBoot Environment構成に合わせ、適切なデータセットに適切にファイルを移動すれば晴れてBE環境になる、ハズ。 手順 独自データセットの解消 Boot Environment構成になく、かつ旧Root on ZFSの公式構成にもない、自分が勝手に切り分けたデータセットを解消する。上表でいう所のzroot/ROOT/usr/includeである。 解消と大層な言葉を使ってみたものの、単にincludeがzroot/usrの1フォルダとなるようファイルをコピーするだけ。 # rsync -aX /usr/include/ /usr/include2 # diff -r /usr/include /usr/include2 # zfs destroy zroot/ROOT/usr/include # mv /usr/include2 /usr/include rsyncを使っているのは念のため拡張属性もコピーしときたいから。特に気にしなければcpでおkだし、基本的には気にする必要もない。 /usr/homeも独自構成ではあるが、BE環境には影響しないので特に何もしない。 Boot Environment環境にないデータセットの解消 Boot Environment構成にない旧Root on ZFS構成のデータセットを解消する。作業内容は独自データセットの解消と同じで、対象は次のとおり。 zroot/ROOT/usr/ports/distfiles zroot/ROOT/usr/ports/packages zroot/ROOT/var/db zroot/ROOT/var/db/pkg zroot/ROOT/var/empty zroot/ROOT/var/run 稼働中のシステムで/varをこねくり回すのは怖いので、FreeBSDのインストーラのシェル(Live環境)で作業する方が安全だろう。というわけで、今後のコマンド例はLive環境を想定している。 普通にzpool importするとLive環境の/に上書きマウントされてしまうので、-Rオプションでルートを指定してマウントすべし。 # mkdir /tmp/altroot # zpool import -R /tmp/altroot zroot # LD_LIBRARY_PATH=/tmp/altroot/usr/local/lib /tmp/altroot/usr/local/bin/rsync -aX ... # zfs destroy ... この作業を終えた時点で、zrootのデータセット構成がBoot Environemtの構成と同一になっていることが重要。 旧Root on ZFS環境のマウントポイントの補正 後続の処理のため、旧Root on ZFS環境の各マウントポイントをzroot/ROOTから継承した設定に変更する。 具体的にはmountpointのSOURCEがinherited from zroot/ROOT/~となるようにする。 # zfs inherit mountpoint zroot/ROOT/tmp zroot/ROOT/usr zroot/ROOT/var 旧Root on ZFS環境はzroot/ROOT以下に全てが収まっているので、これをいったんROOT2として退避する。こうすれば旧環境を温存したままBE環境を構築できる算段。 一旦プールをエクスポートし、自動マウントはせずに再度インポートする。 # zpool export zroot # zpool import -N -R /tmp/altroot zroot 既存環境をリネーム # zfs rename zroot/ROOT zroot/ROOT2 既存環境のルートのマウントポイントを変更しマウント。ここで先に行った補正が活きてくる。始祖データセットのマウントポイントの変更だけで、子データセットのマウントポイントを一気に変えることができる。 # zfs set mountpoint=/ROOT2 zroot/ROOT2 # zfs mount -a Boot Environment環境の構築 Boot Environment用のデータセットを作る。 # zfs create -o mountpoint=none zroot/ROOT # zfs create -o mountpoint=/ -o canmount=noauto zroot/ROOT/default # zfs mount zroot/ROOT/default # zfs create -o mountpoint=/tmp -o exec=on -o setuid=off zroot/tmp # zfs create -o mountpoint=/usr -o canmount=off zroot/usr # zfs create -o mountpoint=/usr/ports -o setuid=off zroot/usr/ports # zfs create -o mountpoint=/usr/src zroot/usr/src # zfs create -o mountpoint=/var -o canmount=off zroot/var # zfs create -o mountpoint=/var/audit -o exec=off -o setuid=off zroot/var/audit # zfs create -o mountpoint=/var/crash -o exec=off -o setuid=off zroot/var/crash # zfs create -o mountpoint=/var/log -o exec=off -o setuid=off zroot/var/log # zfs create -o mountpoint=/var/mail -o atime=on zroot/var/mail # zfs create -o mountpoint=/var/tmp -o setuid=off zroot/var/tmp # chmod 1777 /tmp/altroot/tmp # chmod 1777 /tmp/altroot/var/tmp zroot/ROOT/defaultを作った直後に手動でマウントすることをお忘れなく。 データセット的には親子関係になく、ファイルシステム的には親子関係がある場合、データセットのマウント順に気を付ける必要がある。 現環境のファイルをBoot Environmentなデータセットにコピー。 # LD_LIBRARY_PATH=/tmp/altroot/usr/local/lib /tmp/altroot/usr/local/bin/rsync -aX /tmp/altroot/ROOT2/ /tmp/altroot/ 起動データセットの変更 起動するデータセットをBoot Environmentにする。 # zpool set bootfs=zroot/ROOT/default zroot ついでに、いにしえのRoot on ZFS環境をマウントしないようにしておく。 # zfs set mountpoint=none zroot/ROOT2 Boot Environmentの起動に失敗するようなら、bootfsをzroot/ROOT2、zroot/ROOT2のマウントポイントを/にすれば、以前の環境がそのまま起動する。 1) 厳密にはある程度自由に構成できるがシステム標準に合わせておいた方がいいかなと freebsd/freebsd_convert_legacy_root_on_zfs_to_boot_environment.txt 最終更新: 2021-04-24 23:02by Decomo