FreeBSDでのZFSに関する覚書
FreeBSDでのZFSに関する覚書
毎回いつも管理しているサーバでのディスクトラブルが発生したときに色々と困ったりするのでブログ記事にまとめておきます。あくまでも個人用のメモという前提ですが、完全に間違っているようでしたらX経由でDMでも下さい。
当方、FreeBSDはVersion2.xから使用して現在の最新は15になるのかな?自分は14.4を使用していますがFreeBSDも長い年月をかけてハードの進化に伴って色々と変わって(進化)してきています。自分が管理しているサーバ、新規に立ち上げたサーバなど色々なケースがあるのですが、長期間管理しているサーバでのトラブルと言えばディスク関連。最近ではSSDも使用し、初期不良(数ヶ月で故障)などもあって嫌でもZFS関連の知識が増えますが、ネット上の先駆者の諸先輩方のブログ記事を読み漁って、その場しのぎで対策するというの毎度のパターン。
今回は今後のためにZFSマイスターを目指しw、ここ数年間で実際にあったトラブル内容や空きサーバを使用して実際に動作確認した内容をまとめてみます。
前提
ここにまとめた内容はFreeBSDのインストーラーで新規にZFSで標準インストールしたシステムのディスク交換の詳細やミラーリング構築したディスクの交換方法をまとめています。ちなみにFreeBSDでのZFSはV7から使えるようになりV8ぐらいから標準仕様になったのかな?
ハードディスクの容量が2TByte以上でシステムを構築する場合は嫌でもZFS一択になるはずなので、3.5インチのハードディスクの場合2020年以降は2TByte以下のハードディスクは既に製造されてない(現在の2TByte以下は在庫ってことです。)いないのでFreeBSDではZFSは必須ってことになりますね。ああ、でも2.5インチハードディスクやSSDもあるのでそうでもないのか?
一応、gpartコマンドとzpoolコマンドぐらいで何とかシステム運用出来るような内容にまとめてあります。システムの設定で重要な点はいくつか記載してあるつもりだけど、ここを参照して「起動しなくなった!」なんてのは一切責任取りませんので、すべて自己の責任の範囲で参照してください。
ブートローダーの形式の確認
「ブートローダーって何のこっちゃ?」って人がいるのかわかりませんが、昨今のコンピューターは起動時にハードディスクを読みに行く際にどのようなOSでもブートローダーという部分を呼んでOSを起動します。その部分がここ20年ぐらいで大別すると2種類になり、色々な諸先輩方のブログを読んでハマるケースはそのブートローダーに影響するハードウェアの情報が未記入。印象ではどのブートローダーを使用しているのか記載されずにディスク修復方法だけ記載されているのが多いイメージ。FreeBSDは高性能がゆえに結構古いハードでも動作してしまうので、サーバの利用目的によってはCore2Duo時代のサーバでも何ら問題なかったりします。
まずはじめにここ20年前後でディスク関連で大きく変わった点としてはブートローダーの形式。簡単に言うと従来の
BIOS(Basic Input/Output System)
と現在主流の
UEFI (Unified Extensible Firmware Interface)
先に記載しましたが色々なブログを参考にするとどちらのブートローダーベースで記載されているのかわからないケースが殆どで、UEFI形式でシステムインストーラーでインストールされたシステムにBIOS形式のブートローダーだけインストールしてミラーリング修復したりしたら、次回のトラブルで2度と起動しなくなってしまうなんてケースも普通に発生したりします。
残念ながらZFSのミラーリング機能はブートローダー部分はミラーリングされていませんので、ミラーリング構成でZFSをインストールした際には、自分でブートローダー部分を書き込まないといけません。
このブートローダーに関して「この人なんでこんな事書いているの?」なんて思う人もいるかと思いますが、FreeBSDの標準インストーラーでのディスクフォーマット(手動でパーティションを切る猛者には関係ない話ですね)はシステムがBIOS形式かUEFI形式かを判別してブートローダーをインストールしてくれます。なのでFreeBSDが動作しているシステムでどちらのブートローダーで起動しているか知らない人もいたりするかと思います。稼働しているシステムがどちらのブートローダーで起動されているかを調べるには
sysctl machdep.bootmethod
machdep.bootmethod: UEFI
で、ブートローダーの形式がわかります。上記の例はUEFIブートです。
sysctl machdep.bootmethod
machdep.bootmethod: BIOS
上記がBIOSブートとなります。
ブート方式を調べるその他の方法としては、
efivar -l
で「efivar: error listing variables: Function not implemented」と言うようなエラーが出た場合はBIOSブートになります。
判断基準としては2011年以前の古いハードや2TByte以下の起動ディスクの場合はBIOS、2011年以降のハードやシステムをインストールしているディスクが2T以上の場合はUEFIという感じでしょうか?2011年以前でもUEFIをサポートしているマザーボードもあったりするので、実際には「使用しているハードによる」っと考えるのが一番良いのかな?とにかくそんな人がいるのかわからないけど、古めのハードに最近のFreeBSDを何も考えずに標準インストールした人は使用しているブートローダーを確認しておいた方がよいです。
FreeBSDのディバイス構成(/dev以下に作成されるデバイスファイル)
これが正しいのかわかりませんがFreeBSDのどのバージョンかわかりませんが、接続したデバイスのデバイスファイルは/dev以下にSATAデバイスだとadaX(Xは数字でゼロから始まる)、USB経由のデバイス(外付けハードディスクやUSBメモリー)daX(Xは数字でゼロから始まる)で接続されるという記載がどこかのブログにあったのですが、これほぼこの通りなんですけどハードウェア構成によってはSATAディスクもdaXでデバイス認識されるみたいです。SCSIコントローラー+SATAコントローラー構成だとSATAディバイスもdaXで接続されるハードウェアが存在しました。なので一概にadaXはSATA、daXはUSBという認識は持たない方がよいかと思います。一部の古いハードだけかもしれませんけどね。
/dev以下に作成された各adaX、daXのX部分はインターフェイスIDで割り振られます。USBに関してはデバイスを接続した順番が考慮されるので、USB経由で外部デバイスに接続する場合、インストール状態によっては問題を引き起こすのでどのUSBの口が一番若いポート番号なのかを把握しておいた方がよかと思います。USBの接続場所を変更しなければ問題ありませんが、複数台のUSBデバイスを接続した状態でシステムを構築した場合、再起動後、デバイスIDが変わってしまう場合があります。
以下に/dev以下に接続されたSATA SSDののadaXデバイスの一覧を示します。
rw-r----- 1 root operator 0x6e 4月 22 05:41 /dev/ada0
crw-r----- 1 root operator 0x6f 4月 22 05:41 /dev/ada0p1
crw-r----- 1 root operator 0x70 4月 22 05:41 /dev/ada0p2
crw-r----- 1 root operator 0x71 4月 22 05:41 /dev/ada0p3
ada0の後p1〜3は、ada0のパーティション(p)番号を示します。パーティション構成はgpart show <ディバイス名>で
gpart show ada0
=> 40 500118112 ada0 GPT (238G)
40 1024 1 freebsd-boot (512K)
1064 984 - free - (492K)
2048 4194304 2 freebsd-swap (2.0G)
4196352 495921152 3 freebsd-zfs (236G)
500117504 648 - free - (324K)
というに3つのパーティションがあることがわかるかと思います。ada0pXの数字は上記に表示された1〜3を示しています。ちなみに上記は実際にFreeBSDの13.xのインストーラーのディフォルトインストールで構成されたパーティションとなります。freebsd-boot、freebsd-swap、freebsd-zfsはそれぞれのパーティションの役割を意味しています。名前の通りブート、スワップ、ZFSファイル・システムという内容になります。
各パーティションにはラベル名を指定することが出来ます。このラベル名が中々曲者というか理解しておかないと、後々厄介な事になるので一応簡単に記載しておきますが、
gpart show -l ada0
=> 40 500118112 ada0 GPT (238G)
40 1024 1 gptboot0 (512K)
1064 984 - free - (492K)
2048 4194304 2 swap0 (2.0G)
4196352 495921152 3 zfs0 (236G)
500117504 648 - free - (324K)
上記が先ほどのコマンドに-lオプションを指定して表示した各パーティションのラベル名となります。gptboot0、swap0、zfs0が各パーティションのラベル名(FreeBSDのインストーラーが名付けた)になります。
なぜここで何故各パーティションのラベル名を把握しておく必要があるかというとZFSのミラーリング等のマウント対象パーティションはデバイス名、またはラベル名の両方で構築出来てしまいます。ここは非常に混乱するところなのですが、FreeBSD(14.4を使用)のインストーラー標準で1台の256GByteのディスクにインストールした場合のZFS構成をzpool statusで表示してみると
zpool status
pool: zroot
state: ONLINE
config:
NAME STATE READ WRITE CKSUM
zroot ONLINE 0 0 0
ada0p3 ONLINE 0 0 0
errors: No known data errors
上記のようにパーティション名ada0p3で構成されています。
ZFSで推奨されるのはラベル名指定で/dev/gpt以下にgptスキームでフォーマットされたディスクのラベル名でデバイスファイルが存在するはずなのですが、システムの標準インストーラーで初期化したディスク構成では、
ls /dev/gpt/
gptboot0
っとパーティション番号1番のラベル名gptboot0しか存在しません。本来ならばシステムインストール後の/dev/gptにはgptboot0,swap0,zfs0の最低3つが存在し、上記のzpool statusの「ada0p3」の部分は「gpt/zfs0」でないとおかしいはずです。ちなみにgpart modifyでラベル名の変更が出来るので、以下のように同じ名前や異なる名前を指定しても上記の/dev/gptにはデバイスファイルは作成されませんでした。
gpart modify -i 2 -l swap0 /dev/ada0(パーティション2のラベル名をswap0へ変更)
gpart modify -i 3 -l zfs0 /dev/ada(パーティション3のラベル名をzfs0へ変更)
システム稼働中は変更できないだけなのかもしれませんし、何か別の問題があるのかもしれません。
もしZFSでミラーリング構成に変更する、ミラーリングディスクを交換する場合はデバイス名で構成されているのかラベル名で構成しているのか把握しておく必要があります。一番の問題はデバイス名とラベル名両方とも混ぜて指定出来てしまう事かと思いますが、先に記載した「インストール状態」でラベル名を指定してUSB接続のデバイスを接続すればUSBポートのインデックスIDは関係なくなりZFSが接続されたディスクのラベル名を参照するので、どのUSBポートに接続してもシステム起動に支障がなくなります。
デバイス名orラベル名の話に戻すと、どちらでもミラーリング構成が出来て問題ありませんが、次回ミラーリングディスク交換の際混乱してしまうので注意が必要です。
ちなみに以下は実際にディスクを交換してミラーリングが開始(データが残っているディスクから新規ディスクへデータコピー)されているresilvering中の内容を示します。
zpool attach zroot /dev/ada0p4 /dev/da0p4
# zpool status
pool: zroot
state: ONLINE
status: One or more devices is currently being resilvered. The pool will
continue to function, possibly in a degraded state.
action: Wait for the resilver to complete.
scan: resilver in progress since Mon Apr 27 06:03:33 2026
1.76G / 1.76G scanned, 125M / 1.76G issued at 24.9M/s
111M resilvered, 6.90% done, 00:01:07 to go
remove: Removal of vdev 1 copied 148K in 0h0m, completed on Fri Apr 24 16:50:58 2026
96 memory used for removed device mappings
config:
NAME STATE READ WRITE CKSUM
zroot ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
ada0p4 ONLINE 0 0 0
da0p4 ONLINE 0 0 0 (resilvering)
errors: No known data errors
上記はシステムで標準インストールされたada0p4デバイスへ対して、USB接続したda0p4をzrootプールに追加した直後のデータコピー中(resilvering)状態となっています。
また、ミラーリングをデバイス名とラベル名を指定したときの中の内容を以下に示します。
zpool attach zroot /dev/ada0p4 /dev/gpt/zfs1
# zpool status
pool: zroot
state: ONLINE
status: One or more devices is currently being resilvered. The pool will
continue to function, possibly in a degraded state.
action: Wait for the resilver to complete.
scan: resilver in progress since Mon Apr 27 02:14:31 2026
1.76G / 1.76G scanned, 109M / 1.76G issued at 21.9M/s
94.2M resilvered, 6.07% done, 00:01:17 to go
remove: Removal of vdev 1 copied 148K in 0h0m, completed on Fri Apr 24 16:50:58 2026
96 memory used for removed device mappings
config:
NAME STATE READ WRITE CKSUM
zroot ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
ada0p4 ONLINE 0 0 0
gpt/zfs1 ONLINE 0 0 0 (resilvering)
errors: No known data errors
上記はada0p4(デバイスファイル/dev/ada0p4)へパーティション名gpt/zfs1(/dev/gpt/zfs1)をzrootプールに追加した直後の内容となります。
うだうだと長い説明になってしまいましたが、この部分を総括するとZFSでは、デバイスファイル名、gptフォーマットで名付けたラベル名のどちらでも指定出来てしまう事を把握して置くべきという事です。
あとからシステムディスクをミラーリング化する
ZFSってのは色々便利で1台のディスクでシステム構築した後からでもディスクを追加してミラーリングシステムに出来たりします。この機能を上手く使用すれば既存のシステムディスクを新しいディスクに交換するときにもこのミラーリング機能を使えば簡単に行うことが出来ます。
昔ながらのサーバ屋さんはディスク交換はパーティションごとのddでコピーなんて当たり前だと思っている人もいたり、私も長年サーバを止めてハードディスクをハードディプリケーターでコピーして入れ替えというもっとも安全な方法を取ってきましたが、ZFSのミラーリング機能を使えばシステムを最小限停止させるだけでディスク交換を行えたりします。手間暇を考えると一長一短がありますが、使用している環境に合わせて楽で安全な方法を選ぶのがベストかと思います。
ここでは、シングルディスクで構築したシステムディスクをミラーリング化する前提での内容をまとめます。
まずはミラーリングするディスクをハードへ接続します。ホットスワップ対応のデバイスなら特に問題はないかと思いますが、すでに死にぞこないのシステムディスクをサルベージする際などは再起動せずに何とか内部のデータだけでも吸い上げたいケースは多々あるかと思います。最近ではUSBの転送速度も高速化したのでデータの吸い上げだけならば昔よりもかなり楽にはなりましたね。
取り敢えずミラーリング化するにはシステムディスク同量以上のデバイスをハード本体が認識した状態にします。ここでは、外部にUSB経由でハードディスクを接続してシステムディスクをZFSでミラーリング化してみます。
まずは接続したディスクのフォーマットから。使用しているディスクはかなり古い仕様の512kbyteセクターのAFT非対応の所謂基本中の基本のハードディスクです。
まずはじめに新品ディスクならほぼ問題ありませんが、USBメモリーなどの場合はDOSフォーマットされている場合もあるので、まずは接続したディスク情報の削除してフォーマットを行います。(接続したデバイスは/dev/da0とします。)
gpart destroy -F /dev/da0
gpart create -s gpt /dev/da0
この操作は間違えると元に戻せません。
デバイス名を間違えるとシステムを破損してしまいますので注意してください。
続いてシステムディスクのパーティション情報を新しいディスクにコピーします。一番簡単な方法はgpartのbackupコマンドとrestoreコマンドをパイプで繋ぐ以下の方法です。
gpart backup /dev/ada0 | gpart restore -F /dev/da0
ミラーリングするマスターディスクのデバイスが/dev/ada0、スレーブディスクが先程フォーマットした/dev/da0になります。
# gpart show /dev/ada0
=> 34 488397101 ada0 GPT (233G)
34 6 - free - (3K)
40 532480 1 efi (260M)
532520 1024 2 freebsd-boot (512K)
533544 984 - free - (492K)
534528 4194304 3 freebsd-swap (2G)
4728832 483667968 4 freebsd-zfs (231G)
488396800 335 - free - (168K)
# gpart show /dev/da0
=> 34 488397101 da0 GPT (233G)
34 6 - free - (3K)
40 532480 1 efi (260M)
532520 1024 2 freebsd-boot (512K)
533544 984 - free - (492K)
534528 4194304 3 freebsd-swap (2G)
4728832 483667968 4 freebsd-zfs (231G)
488396800 335 - free - (168K)
restoreコマンドでラベル名はコピー指定していないので、
# gpart show -l /dev/ada0
=> 34 488397101 ada0 GPT (233G)
34 6 - free - (3K)
40 532480 1 efiboot0 (260M)
532520 1024 2 gptboot0 (512K)
533544 984 - free - (492K)
534528 4194304 3 swap0 (2G)
4728832 483667968 4 zfs0 (231G)
488396800 335 - free - (168K)
# gpart show -l /dev/da0
=> 34 488397101 da0 GPT (233G)
34 6 - free - (3K)
40 532480 1 (null) (260M)
532520 1024 2 (null) (512K)
533544 984 - free - (492K)
534528 4194304 3 (null) (2G)
4728832 483667968 4 (null) (231G)
488396800 335 - free - (168K)
のように(null)と表示されています。ちなみにですがgpartのbackp&restoreは古いrestore側のパーテイション情報は上書きされます。gpartのcreateコマンドでスキームをgpt指定されたディスクならばrestoreだけでパーテイションを切る事が出来ます。
続いてrestoreしたパーテイションにラベル名を指定します。
gpart modify -i 1 -l efiboot1 /dev/da0
gpart modify -i 2 -l gptboot1 /dev/da0
gpart modify -i 3 -l swap1 /dev/da0
gpart modify -i 4 -l zfs1 /dev/da0
ミラーリングするのでマスターのパーテイション名の0(ゼロ)の部分を1に指定してわかりやすく指定しています。ラベル名が変更されたことを確認してみます。
# gpart show -l /dev/da0
=> 34 488397101 da0 GPT (233G)
34 6 - free - (3K)
40 532480 1 efiboot1 (260M)
532520 1024 2 gptboot1 (512K)
533544 984 - free - (492K)
534528 4194304 3 swap1 (2G)
4728832 483667968 4 zfs1 (231G)
488396800 335 - free - (168K)
ちなにみに上記を見て不思議に思った方もおられるかと思います。bootローダー部分が2つあります。これはUEFIシステムとBIOS/Legacyシステムの両方で起動可能にするためです。互換性を確保するためにUEFIベースのハードでは2つのブートローダーがインストールされています。
gpart show -l /dev/ada0
=> 40 500118112 ada0 GPT (238G)
40 1024 1 gptboot0 (512K)
1064 984 - free - (492K)
2048 4194304 2 swap0 (2.0G)
4196352 495921152 3 zfs0 (236G)
500117504 648 - free - (324K)
ちなみに古いBIOSベースのハードウェアの場合は当然ですが上記のようにUEFIはインストールされません。gptbootは2TByte以下のデバイスしか対応していないのでハード的な制限があります。
システムがブートローダーを起動時に見つけやすくするためにブートローダーはパーテションの初期に配置するのがセオリーということですね。
ちなみどちらのブートローダーが使われているか調べてみると
# sysctl machdep.bootmethod
machdep.bootmethod: UEFI
UEFIでした。調べてはいませんがマザーボード設定でBIOSとUEFIを切り替えられるのかな?マザーボードでBIOS指定しても起動できるということですね。どちらにしてもFreeBSDのインストーラーは14.4時点では古いハードウェアもしっかりとサポートされているということになります。
それと先のパーテイション情報をみるとディスクの開始ブロックは34になっています。これはGPTパーティションのヘッダーサイズは34ブロック(セクター)なので本来は34から開始すべきですが、6ブロック(512X6=3,072byte)分フリー部分として40ブロックからインストールされています。これは4,096byteブロックのハードを考慮したもので
512バイト x 34ブロック=17,408byte
17,408 byte / 4096 = 4.5ブロック
上記の4.5ブロックを整数に丸めると5になるので
5x4096 byte / 512 = 40ブロック
という事になり開始ブロックは40となります。なので最近のハードウェアではすべて40ブロックが開始となり、ここで示した例と同じようなる事は滅多にありません。ちなみに今回使用したハードディスクをgpart listで確認してみると
# gpart list /dev/ada0
Geom name: ada0
modified: false
state: OK
fwheads: 16
fwsectors: 63
last: 488397134
first: 34
entries: 128
scheme: GPT
Providers:
1. Name: ada0p1
Mediasize: 272629760 (260M)
Sectorsize: 512
Stripesize: 0
Stripeoffset: 20480
Mode: r1w1e2
efimedia: HD(1,GPT,2226788b-41dc-11f1-8d5b-a4bb6da25010,0x28,0x82000)
rawuuid: 2226788b-41dc-11f1-8d5b-a4bb6da25010
rawtype: c12a7328-f81f-11d2-ba4b-00a0c93ec93b
label: efiboot0
length: 272629760
offset: 20480
type: efi
index: 1
end: 532519
start: 40
2. Name: ada0p2
Mediasize: 524288 (512K)
Sectorsize: 512
Stripesize: 0
Stripeoffset: 272650240
Mode: r0w0e0
efimedia: HD(2,GPT,222aff4f-41dc-11f1-8d5b-a4bb6da25010,0x82028,0x400)
rawuuid: 222aff4f-41dc-11f1-8d5b-a4bb6da25010
rawtype: 83bd6b9d-7f41-11dc-be0b-001560b84f0f
label: gptboot0
length: 524288
offset: 272650240
type: freebsd-boot
index: 2
end: 533543
start: 532520
3. Name: ada0p3
Mediasize: 2147483648 (2.0G)
Sectorsize: 512
Stripesize: 0
Stripeoffset: 273678336
Mode: r1w1e0
efimedia: HD(3,GPT,222cf560-41dc-11f1-8d5b-a4bb6da25010,0x82800,0x400000)
rawuuid: 222cf560-41dc-11f1-8d5b-a4bb6da25010
rawtype: 516e7cb5-6ecf-11d6-8ff8-00022d09712b
label: swap0
length: 2147483648
offset: 273678336
type: freebsd-swap
index: 3
end: 4728831
start: 534528
4. Name: ada0p4
Mediasize: 247637999616 (231G)
Sectorsize: 512
Stripesize: 0
Stripeoffset: 2421161984
Mode: r1w1e1
efimedia: HD(4,GPT,22307305-41dc-11f1-8d5b-a4bb6da25010,0x482800,0x1cd43000)
rawuuid: 22307305-41dc-11f1-8d5b-a4bb6da25010
rawtype: 516e7cba-6ecf-11d6-8ff8-00022d09712b
label: zfs0
length: 247637999616
offset: 2421161984
type: freebsd-zfs
index: 4
end: 488396799
start: 4728832
Consumers:
1. Name: ada0
Mediasize: 250059350016 (233G)
Sectorsize: 512
Mode: r3w3e6
Sectorsizeが512になっている事が確認出来ます。
ちなみに1TbyteのAFT対応のハーディスクの場合、
1. Name: ada0
Mediasize: 1000204886016 (932G)
Sectorsize: 512
Stripesize: 4096
Stripeoffset: 0
Mode: r3w3e6
のようにSectorsizeは512ですが、Stripesizeが4096と表示され、ブートローダーは
=> 40 1953525088 ada0 GPT (932G)
40 532480 1 efi (260M)
532520 1024 2 freebsd-boot (512K)
533544 984 - free - (492K)
534528 4194304 3 freebsd-swap (2G)
4728832 1948794880 4 freebsd-zfs (929G)
1953523712 1416 - free - (708K)
40ブロックから開始されefiからインストールされています。FreeBSD14.4で512バイトセクターのハードディスクにおいてgpartでのパーティション追加でスタートブロック34は指定するとエラーとなります。インストーラーでは34ブロックが開始となっていますがgpartでは指定できず(40〜)、gpartのbackup&restoreでは34ブロックからfreeフロックが定義されるという何とも不思議な状態となります。4096バイトブロックに合わせての仕様ですが、この辺もなぜそうなっているのか知らないと、混乱してしまう1つの要因となりますね。
ブートローダーのインストール
続いてブートローダーのインストール。UEFIサポートしているシステムの場合は2つのブートローダーをミラーリングディスクにコピーする必要があります。
・UEFI用 (efiboot) の更新
newfs_msdos -F 32 -c 1 /dev/da0p1
mkdir /mp
mount -t msdosfs /dev/da0p1 /mp
mkdir -p /mp/EFI/BOOT
cp /boot/loader.efi /mp/EFI/BOOT/BOOTX64.EFI
umount /mp
rm -r /mp
まずはパーティション1/dev/da0p1をMS-DOS形式でフォーマットします。FATタイプ(-F)は32、クラスターサイズ(-c)は1を指定。適当に/mpディレクトリを作成してからマウントし、/mp/EFI/BOOTディレクトリを作成。続いてブートローダーをコピーしています。
以下実際のnewfwログ
# newfs_msdos -F 32 -c 1 /dev/da0p1
/dev/da0p1: 524256 sectors in 524256 FAT32 clusters (512 bytes/cluster)
BytesPerSec=512 SecPerClust=1 ResSectors=32 FATs=2 Media=0xf0 SecPerTrack=63 Heads=255 HiddenSecs=0 HugeSectors=532480 FATsecs=4096 RootCluster=2 FSInfo=1 Backup=2
続いてBIOS用 (gptboot) の更新の更新
・BIOS用 (gptboot) の更新
gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 2 /dev/da0
gpartコマンドでbootコードを/dev/da0のパーテション番号(-i)2へコピーします。
以下実際のgpart bootcodeのログ
gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 2 /dev/da0
partcode written to da0p2
bootcode written to da0
上記2つのブートローダーのコピーはデバイス名とパーテション番号を確認の上、編集してコピペすれば問題ないと思います。これまでgpart bootcodeは何度も行いましたが、エラーが発生したことはないです。まあブートローダーのインストールでエラーが出たら、もうお手上げですかね?
ここからやっとミラーリングの開始です。まずはzpool statusで確認。
pool: zroot
state: ONLINE
config:
NAME STATE READ WRITE CKSUM
zroot ONLINE 0 0 0
ada0p4 ONLINE 0 0 0
errors: No known data errors
システムのインストーラーではada0p4のデバイスファイル名で構築されているので、ここでは同じようにデバイス名でミラーリング構成してみます。
zpool attach zroot /dev/ada0p4 /dev/da0p4
# zpool status
pool: zroot
state: ONLINE
status: One or more devices is currently being resilvered. The pool will
continue to function, possibly in a degraded state.
action: Wait for the resilver to complete.
scan: resilver in progress since Mon Apr 27 06:03:33 2026
1.76G / 1.76G scanned, 125M / 1.76G issued at 24.9M/s
111M resilvered, 6.90% done, 00:01:07 to go
remove: Removal of vdev 1 copied 148K in 0h0m, completed on Fri Apr 24 16:50:58 2026
96 memory used for removed device mappings
config:
NAME STATE READ WRITE CKSUM
zroot ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
ada0p4 ONLINE 0 0 0
da0p4 ONLINE 0 0 0 (resilvering)
errors: No known data errors
ミラーリングを開始した直後の状態。resilveringしているのがわかります。
ちなみにgptのラベル名でもミラーリング化出来ます。USBデバイスの場合はgptラベル名でミラーリングした方がUSBポートの接続場所を変更してもトラブルが発生しませんので、ラベル名の方画よいでしょう。
zpool attach zroot /dev/ada0p4 /dev/gpt/zfs1
先にも記載しましたがzpoolで指定するデバイスをデバイスファイル名&デバイスラベル名で指定出来てしまうので混乱を招きます。外部ドライブを使用せずマザーボード上のインタフェースだけで完結する場合はデバイスファイル名指定で問題ありません。
以下は、上記のzpool attachを実行してミラーリング化した直後のzpool statusです。
# zpool status
pool: zroot
state: ONLINE
status: One or more devices is currently being resilvered. The pool will
continue to function, possibly in a degraded state.
action: Wait for the resilver to complete.
scan: resilver in progress since Mon Apr 27 02:14:31 2026
1.76G / 1.76G scanned, 109M / 1.76G issued at 21.9M/s
94.2M resilvered, 6.07% done, 00:01:17 to go
remove: Removal of vdev 1 copied 148K in 0h0m, completed on Fri Apr 24 16:50:58 2026
96 memory used for removed device mappings
config:
NAME STATE READ WRITE CKSUM
zroot ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
ada0p4 ONLINE 0 0 0
gpt/zfs1 ONLINE 0 0 0 (resilvering)
errors: No known data errors
以上で、システムディスクのミラーリング化が出来ました。
しかしながらこれで終わりというわけにはいきません。この状態でミラーリング元のディスクをofflineして再起動すると見事に起動時にコケてしまうのでfstabを編集する必要があります。
cat /etc/fstab
# Device Mountpoint FStype Options Dump Pass#
/dev/gpt/efiboot0 /boot/efi msdosfs rw 2 2
/dev/ada0p3 none swap sw 0 0
上記は1台のハードディスクでシステムでインストールされたfstabになります。マウントポイント2つが記載されており、マウントポイントはブートローダーとスワップエリアです。この2つのマウントポイントでシステム起動に必要になるのは スワップエリア。/boot/efiのマウントポイントはマウントしてもしなくても起動する事ができます。そのため、システムディスクをミラーリング化した場合、以下のように"rw"の部分を"rw,failok"に変更し、更にスワップポイントは2台分のディスクのスワップエリアを記載しておきます。
# Device Mountpoint FStype Options Dump Pass#
/dev/gpt/efiboot0 /boot/efi msdosfs rw,failok 2 2
#/dev/gpt/efiboot1 /boot/efi msdosfs rw,noauto 0
0
/dev/ada0p3 none swap sw 0 0
/dev/da0p3 none swap sw 0 0
スワップエリアはどちらか1台でもマウント出来れば起動出来ます。もしどちらかのスワップポイントが存在しなければ、起動時に
Mounting late filesystem:
swapon: /dev/da0p3: No such file or directory
の警告が表示されます。
/boot/efiのマウントポイントのOptionsに指定した"rw,failok"は"/dev/gpt/efiboot0"デバイスにアクセス出来ればマウントし、アクセス出来なければマウントしません。このefiブートエリアはディフォルトでマウントするように指定されていますが、普段は使用することはありません。frebsd-updateにてブートローダーの更新があった際に使用されるため、通常はマウントしなくても問題ありません。なのでミラーリングディスクの片方がコケたとき、問題なく起動できるように"rw,failok"に変更しておく必要があります。上記のfstabの2行目には念のため2台目のディスクの/boot/efiのマウントポイントを記載してありますが、ミラーリングディスクのどちらかが故障したまま運営しfreebsd-updateを行う場合以外は使用することはまずないでしょう。
※ちなみにOptionには"rw,noauto"を記載してあるので、行頭の#コメントを外して記載しても自分でmountコマンドを叩かない限りマウントされません。もし2台のディスクの/dev/gpt/efibootXをマウントする場合はマウントポイントに注意してください。
FreeBSDでZFSでUSB接続の外付けディスクをミラーリング構成で使用する
この単純なタイトル通りの事を行う人は殆どいないんですかね?ってぐらい参考になるブログが見つからない。単に見落としているだけなのかもしれないけど、あまりに単純すぎて誰も記事に書かないだけ?それともこんなチープ事誰もしていない?これだけUSBメモリーだの100円均一でもUSBデバイス関連の商品が溢れる時代にFreeBSDのシステムにUSB経由でミラーリングディスクつけるなんて人がいてもおかしくないと思うんだけど。そんなわけで自分用に記載しておきます。
ここではシステムディスクとは異なるZFSの新規外付けディスク用プールを作成してシステムディスクとは別なディスク構成を構築します。
この記事のなかに重複した内容を記載していますが、まずはUSB接続したデバイスファイル/dev/daX(Xは0からはじまる数字)の初期化から。
市販されているUSBメモリーの殆どは初期フォーマット済みな物しかありませんので、
gpart destroy -F /dev/da0
gpart create -s gpt /dev/da0
gpart add -t freebsd-zfs -l disk00 /dev/da0
ってな感じで一度破壊して、初期化して、パーティションを切り直し。パーティションラベル名はdisk00にします。(好きな名前に変更してください。)
# gpart show -l
=> 34 488397101 ada0 GPT (233G)
34 6 - free - (3K)
40 532480 1 efiboot0 (260M)
532520 1024 2 gptboot0 (512K)
533544 984 - free - (492K)
534528 4194304 3 swap0 (2G)
4728832 483667968 4 zfs0 (231G)
488396800 335 - free - (168K)
=> 40 3932080 da0 GPT (2G)
40 3932080 1 disk00 (2G)
USB経由で接続した1つ目のUSBメモリーda0(2G)を確認します。
続いてこのデバイスでZpoolを作成します。プール名はZFSのサンプルによく使用されるtankでw
zpool create tank /dev/gpt/disk00
# zpool status
pool: tank
state: ONLINE
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
gpt/disk00 ONLINE 0 0 0
新規のプール名tankが作成され
# df
Filesystem 1K-blocks Used Avail Capacity Mounted on
zroot/ROOT/default 233445752 1594560 231851192 1% /
devfs 1 0 1 0% /dev
/dev/gpt/efiboot0 262128 648 261479 0% /boot/efi
zroot/tmp 231851288 96 231851192 0% /tmp
zroot/var/log 231851692 500 231851192 0% /var/log
zroot/home 231851288 96 231851192 0% /home
zroot/usr/src 231851288 96 231851192 0% /usr/src
zroot/var/audit 231851288 96 231851192 0% /var/audit
zroot/var/crash 231851288 96 231851192 0% /var/crash
zroot/var/tmp 231851288 96 231851192 0% /var/tmp
zroot/usr/ports 231851288 96 231851192 0% /usr/ports
zroot/var/mail 231851364 172 231851192 0% /var/mail
zroot 231851288 96 231851192 0% /zroot
tank 1703648 96 1703552 0% /tank
/tankにマウントされているのが確認できます。
つづいて/tankをミラーリング化します。まずはディスクの用意。
gpart destroy -F /dev/da1
gpart create -s gpt /dev/da1
gpart add -t freebsd-zfs -l disk01 /dev/da1
確認
# gpart show -l
=> 40 3932080 da1 GPT (2G)
40 3932080 1 disk01 (2G)
作成したtankプールにアタッチしてミラーリング化します。
# zpool attach tank /dev/gpt/disk00 /dev/gpt/disk01
# zpool status
pool: tank
state: ONLINE
scan: resilvered 732K in 00:00:01 with 0 errors on Thu Apr 30 11:51:31 2026
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
gpt/disk00 ONLINE 0 0 0
gpt/disk01 ONLINE 0 0 0
errors: No known data errors
これで外部USBメモリー2つをミラーリング化しました。
# glabel status
Name Status Components
gpt/efiboot0 N/A ada0p1
gpt/gptboot0 N/A ada0p2
gpt/disk00 N/A da0p1
gpt/disk01 N/A da1p1
外部ディスクをgpartでパーティション理由してどのデバイスがどのラベルなのか調べるにはglabel statusで確認ができます。
以上で、USB接続の外部デバイスをミラーリングディスクとして接続出来ました。
続いてはディスクの運用。USB接続のデバイスを色々な運用方法が考えらますが、まずは接続したまま再起動。
# df
Filesystem 1K-blocks Used Avail Capacity Mounted on
zroot/ROOT/default 233445772 1594516 231851256 1% /
devfs 1 0 1 0% /dev
/dev/gpt/efiboot0 262128 648 261479 0% /boot/efi
tank 1703432 96 1703336 0% /tank
zroot/usr/ports 231851352 96 231851256 0% /usr/ports
zroot/var/log 231851760 504 231851256 0% /var/log
zroot/var/audit 231851352 96 231851256 0% /var/audit
zroot/var/crash 231851352 96 231851256 0% /var/crash
zroot/usr/src 231851352 96 231851256 0% /usr/src
zroot/tmp 231851352 96 231851256 0% /tmp
zroot/home 231851352 96 231851256 0% /home
zroot/var/mail 231851428 172 231851256 0% /var/mail
zroot 231851352 96 231851256 0% /zroot
zroot/var/tmp 231851352 96 231851256 0% /var/tmp
そのまま/tankにマウントされていました。リモートで再起動しても外部USBディスクは常時見えているという感じですね。続いてはZpoolのマウント/アンマウント。
zpool export tank(アンマウント)
zpool import tank(マウント)
zpoolだとexport/importコマンドになります。ちなみにexportしてUSBデバイスを接続したままの状態で再起動してみると、
# df
Filesystem 1K-blocks Used Avail Capacity Mounted on
zroot/ROOT/default 233445724 1594516 231851208 1% /
devfs 1 0 1 0% /dev
/dev/gpt/efiboot0 262128 648 261479 0% /boot/efi
zroot/var/log 231851712 504 231851208 0% /var/log
zroot/usr/ports 231851304 96 231851208 0% /usr/ports
zroot/home 231851304 96 231851208 0% /home
zroot/tmp 231851304 96 231851208 0% /tmp
zroot/usr/src 231851304 96 231851208 0% /usr/src
zroot/var/audit 231851304 96 231851208 0% /var/audit
zroot/var/crash 231851304 96 231851208 0% /var/crash
zroot/var/mail 231851380 172 231851208 0% /var/mail
zroot 231851304 96 231851208 0% /zroot
zroot/var/tmp 231851304 96 231851208 0% /var/tmp
マウントされずに起動されています。
続いてUSBディバイスを再度マウントしてみます。zpoolのプール名を忘れてしまった場合などはimportコマンドを引数なしで実行すると
# zpool import
pool: tank
id: 2441220924155688897
state: ONLINE
action: The pool can be imported using its name or numeric identifier.
config:
tank ONLINE
mirror-0 ONLINE
gpt/disk00 ONLINE
gpt/disk01 ONLINE
未接続のプール一覧が表示されるので、名前を忘れてしまっても困ることはありません。
# zpool import tank
# zpool status
pool: tank
state: ONLINE
scan: resilvered 732K in 00:00:01 with 0 errors on Thu Apr 30 11:51:31 2026
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
gpt/disk00 ONLINE 0 0 0
gpt/disk01 ONLINE 0 0 0
errors: No known data errors
importしてして、状態を確認してみました。
続いてミラーリング化を止めてみます。disk01をミラーリングから外してシングルディスク化にしてみます。
zpool detach tank /dev/gpt/disk01
# zpool status
pool: tank
state: ONLINE
scan: resilvered 732K in 00:00:01 with 0 errors on Thu Apr 30 11:51:31 2026
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
gpt/disk00 ONLINE 0 0 0
errors: No known data errors
ちなみにもうdisk01一度接続して、今度はdisk00を外してみます。
# zpool attach tank /dev/gpt/disk00 /dev/gpt/disk01
# zpool detach tank /dev/gpt/disk00
# zpool status
pool: tank
state: ONLINE
scan: resilvered 1.17M in 00:00:01 with 0 errors on Thu Apr 30 12:51:42 2026
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
gpt/disk01 ONLINE 0 0 0
errors: No known data errors
簡単にいつでもミラーリング化を追加・解除ができます。今回の例のような外付けディスクで運用しているシステムならばディスク交換はいとも簡単に出来てしまいますね。
ここまでを簡単に総括すると
- exportせずに再起動したUSBディスクはimportされた状態で起動される
- exportしたディスクは後からimportすることが出来る。再起動後でもimprotできる。
- ミラーリングディスクの追加・解除は簡単に行える
まあ、当たり前の事を書いているんですけど、一応残しておきます。
これらのやり方をマスターしてればFreeBSDで運用サーバーで、USB接続の外部ドライブを用意してZFSで接続し、基本的な運用(マウント/アンマウント)は簡単におこなえ、しかもミラーリングも出来ますね。データのバックアップ等には役立つかと思います。
ちなみに何故このような事をまとめたかっというと過去に苦い経験があるからです。FreeBSDでUFS2がリリースされた頃、当時はSCSIインターフェイスをPCI拡張カードで増設して、外部にディスク2台構成のハードウェアによるRAID1ディスクを接続して運用していたのですが、ハードディスクが壊れる頃にはハードRAIDの装置のサポートはとっくに終わり、同サイズ以上のディスクを調達してディスク交換してみたもののディスクを認識できず、結局10万円以上かけて構築したハードRAID1装置は単なる外部ディスクで終わってしまいました。変なよくわからないハードRAIDなんてつかってはダメってことですね。基本的にはRAID1以上でレベルを選択できるハードウェアじゃないと使い物にならないと思ってます。簡易的なハードRAIDシステムは結構色々なメーカーから販売されているみたいですが、私と同じような目に合わないように気をつけてください。ディスクとしては使えるけど、運用上問題があるのでは意味がありませんからね。
zpoolのミラーリングディスクの操作
ここからはミラーリングディスク故障ときの交換など運用に関してです。正直あまり頻繁に発生するのは困るけどw
zpoolで構築したミラーリングディスク構成をそのままにディスク交換を行うには、
- 交換対象ディスクをofflineにする
- 既存ディスクのパーティション情報の確認(生きているディスクに合わせる)
- ディスクハード交換(ホットスワップ対応でなければ再起動)
- 新規ディスクパーティション設定
- システムディスクの場合ブートローダーのコピー(2つある場合が殆ど)
- replace実行
- resilvering(ミラーのコピー)の状態確認
- 交換したディスクのディスクSTATEがONLINEになりresilveredになったら完了
と以上の流れになります。経験則から3の「ディスクハード交換」の際、ミラーリングディスクでSATA0番を交換するとディスクを参照しにいってもブートローダーが見つからず起動出来なくなってしまうケースがありました。
この場合、SATA0のディスクのSATAケーブルを外した状態で起動し、SATA1以降のミラーリングディスクのブートローダーを読み込んでシステムが起動したらSATA0のSATAケーブルを戻して、一時的にシステムを騙して起動させるケースがありました。通常のシステムではSATAチャンネルの若い番号からアクセスしていくのでSATA0に何も入っていない新規ディスクが接続されていると起動出来なくなるのは当然の結果ですね。ライブCDなどで外部ディバイス優先でシステムを起動しても対応は出来るとおもいますが、準備がない場合の荒業として一応記載しておきます。SATAポートは一応ホットスワップなので起動後にケーブルの接続を行っても特に問題ありません。
続いて、ここにこれまで経験したいくつかのzpoolミラーリング化で発生したエラー事例を紹介します。
zpoolミラーリングエラーケース1
# zpool status
pool: zroot
state: DEGRADED
status: One or more devices could not be opened. Sufficient replicas exist for
the pool to continue functioning in a degraded state.
action: Attach the missing device and online it using 'zpool online'.
see: https://openzfs.github.io/openzfs-docs/msg/ZFS-8000-2Q
scan: resilvered 2.20M in 00:00:02 with 0 errors on Mon Apr 27 06:12:34 2026
remove: Removal of vdev 1 copied 148K in 0h0m, completed on Fri Apr 24 16:50:58 2026
96 memory used for removed device mappings
config:
NAME STATE READ WRITE CKSUM
zroot DEGRADED 0 0 0
mirror-0 DEGRADED 0 0 0
ada0p4 UNAVAIL 0 0 0 cannot open
da0p4 ONLINE 0 0 0
zpool offline zroot ada0p4
上記は故意的に内部のSATAケーブルを外して起動してみました。ディスクのSTATEがUNAVAILになっています。
zpoolミラーリングエラーケース2
zpool status
pool: zroot
state: DEGRADED
status: One or more devices has been removed by the administrator.
Sufficient replicas exist for the pool to continue functioning in a
degraded state.
action: Online the device using zpool online' or replace the device with
'zpool replace'.
scan: resilvered 1.02G in 00:01:40 with 0 errors on Tue Jan 7 07:21:42 2025
config:
NAME STATE READ WRITE CKSUM
zroot DEGRADED 0 0 0
mirror-0 DEGRADED 0 0 0
ada0p3 ONLINE 0 0 0
ada1p3 REMOVED 0 0 0
errors: No known data errors
続いて上記はSSDでミラーリング化しているシステムでSSDが完全死亡した例です。zpoolによって強制的にディスクSTATEがREMOVEになっています。このケースが一番多いかな?
zpoolミラーリングエラーケース3
zpool status
pool: zroot
state: ONLINE
status: One or more devices has experienced an unrecoverable error. An
attempt was made to correct the error. Applications are unaffected.
action: Determine if the device needs to be replaced, and clear the errors
using 'zpool clear' or replace the device with 'zpool replace'.
see: https://openzfs.github.io/openzfs-docs/msg/ZFS-8000-9P
config:
NAME STATE READ WRITE CKSUM
zroot ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
ada0p3 ONLINE 0 0 0
ada1p3 ONLINE 5 0 93
errors: No known data error
続いて上記はSSDにREADエラー、チェックサムエラーが発生したケースです。actionにはreplaceしろ!ってメッセージが出ていますが、ディスクはオンラインのままです。
実際に経験したのは上記3つのケースだけです。ケース2のREMOVEDは何度経験したことか...。
では、先のUSB接続の外部ディスク2台でミラーリング構成したzpoolのディスク交換を行ってみます。
zpool status
pool: tank
state: ONLINE
scan: resilvered 1.35M in 00:00:01 with 0 errors on Thu Apr 30 13:24:45 2026
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
gpt/disk01 ONLINE 0 0 0
gpt/disk00 ONLINE 0 0 0
errors: No known data errors
現在の構成はこんな感じ。まずはdisk01をofflineにしてみます。
# zpool offline tank gpt/disk01
# zpool status
pool: tank
state: DEGRADED
status: One or more devices has been taken offline by the administrator.
Sufficient replicas exist for the pool to continue functioning in a
degraded state.
action: Online the device using 'zpool online' or replace the device with
'zpool replace'.
scan: resilvered 1.35M in 00:00:01 with 0 errors on Thu Apr 30 13:24:45 2026
config:
NAME STATE READ WRITE CKSUM
tank DEGRADED 0 0 0
mirror-0 DEGRADED 0 0 0
gpt/disk01 OFFLINE 0 0 0
gpt/disk00 ONLINE 0 0 0
errors: No known data errors
offlineのときのディスク指定はフルパスで記載しなくてもよいという、何とも不思議仕様w。もちろんフルパスで記載しても問題ありません。
offline化するとzpoolのstateはDEGRADEDになり、対象ディスクgtp/disk01はOFFLINEになっているのがわかります。
ここではディスクが壊れているわけではありませんので、ここではそのままonline化してみます。
# zpool online tank gpt/disk01
# zpool status
pool: tank
state: ONLINE
scan: resilvered 216K in 00:00:01 with 0 errors on Thu Apr 30 13:30:30 2026
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
gpt/disk01 ONLINE 0 0 0
gpt/disk00 ONLINE 0 0 0
errors: No known data errors
無事ミラーリングが復活し、すべてのSTATEがONLINEになりました。接続しているディスクが空なのでresilveredがあっという間に終了してscanにその内容が記載されているのがわかるかと思います。
続いてUSBポートに接続しているメモリーカードを他のメモリーカードに入れ替えてから書き込みをしてエラーを発生させてみました。
# zpool status
pool: tank
state: DEGRADED
status: One or more devices has been removed by the administrator.
Sufficient replicas exist for the pool to continue functioning in a
degraded state.
action: Online the device using zpool online' or replace the device with
'zpool replace'.
scan: resilvered 216K in 00:00:01 with 0 errors on Thu Apr 30 13:30:30 2026
config:
NAME STATE READ WRITE CKSUM
tank DEGRADED 0 0 0
mirror-0 DEGRADED 0 0 0
gpt/disk01 REMOVED 0 0 0
gpt/disk00 ONLINE 0 0 0
zpoolのstateはDEGRADEDになりメモリーカード入れ替えたディスクのSTATEはREMOVEDになりました。
新品のメモリーカードに入れ替えたので取り急ぎgpartで状態を確認。
# gpart show
=> 40 3932080 da1 GPT (2G)
40 3932080 1 freebsd-zfs (2G)
=> 1 3932159 da0 MBR (2G)
1 31 - free - (16K)
32 3932128 1 !14 (2G)
da0がMBRになっています。DOSでフォーマットされていますね。
これまでに紹介した方法でgpt形式で初期化してda1のフォーマットをバックアップ&リストアでパーテション情報をコピーしてみました。
# gpart destroy -F /dev/da0
da0 destroyed
# gpart create -s gpt /dev/da0
da0 created
# gpart backup /dev/da1 | gpart restore -F /dev/da0
# gpart show
=> 40 3932080 da1 GPT (2G)
40 3932080 1 freebsd-zfs (2G)
=> 34 3932093 da0 GPT (2G)
34 6 - free - (3K)
40 3932080 1 freebsd-zfs (2G)
3932120 7 - free - (4K)
# gpart show -l
=> 40 3932080 da1 GPT (2G)
40 3932080 1 disk00 (2G)
=> 34 3932093 da0 GPT (2G)
34 6 - free - (3K)
40 3932080 1 (null) (2G)
3932120 7 - free - (4K)
不思議ですねー。da1は40ブロックからなのに、リストアしたda0は34ブロックから開始され、4K丸めされていますw パーティションラベル名は指定してないので(null)になっていますので、disk01にしてみます。
# gpart modify -i 1 -l disk01 /dev/da0
da0p1 modified
# gpart show -l
=> 40 3932080 da1 GPT (2G)
40 3932080 1 disk00 (2G)
=> 34 3932093 da0 GPT (2G)
34 6 - free - (3K)
40 3932080 1 disk01 (2G)
3932120 7 - free - (4K)
da1、da0ともにインデックス1の量量は同じになっていますね。ここで使用したメモリーカードは同じメーカーの2Gbyteのものなのですが、なんか容量が若干違うのかな?w
続いてzpoolをリプレイスしてみます。まずはremoveされたディスクをofflineにします。
# zpool offline tank gpt/disk01
# zpool status
pool: tank
state: DEGRADED
status: One or more devices has been taken offline by the administrator.
Sufficient replicas exist for the pool to continue functioning in a
degraded state.
action: Online the device using 'zpool online' or replace the device with
'zpool replace'.
scan: resilvered 216K in 00:00:01 with 0 errors on Thu Apr 30 13:30:30 2026
config:
NAME STATE READ WRITE CKSUM
tank DEGRADED 0 0 0
mirror-0 DEGRADED 0 0 0
gpt/disk01 OFFLINE 0 0 0
gpt/disk00 ONLINE 0 0 0
errors: No known data errors
続いてリプレイスを実行します。
# zpool replace tank gpt/disk01
# zpool status
pool: tank
state: ONLINE
scan: resilvered 1.24M in 00:00:01 with 0 errors on Thu Apr 30 14:01:23 2026
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
gpt/disk01 ONLINE 0 0 0
gpt/disk00 ONLINE 0 0 0
errors: No known data errors
殻のメモリーカードなので瞬時にresilverdになり2つのディスクがミラーリング構成されました。replaceコマンドもstatusコマンドで表示されたデバイス名称で問題なくリプレイス出来ますねw
このミラーリング状態で、システムをシャットダウンして、USBメモリーのポートを入れ替えて再起動してみます。
# gpart show
=> 40 3932080 da0 GPT (2G)
40 3932080 1 freebsd-zfs (2G)
=> 34 3932093 da1 GPT (2G)
34 6 - free - (3K)
40 3932080 1 freebsd-zfs (2G)
3932120 7 - free - (4K)
# zpool status
pool: tank
state: ONLINE
scan: resilvered 1.24M in 00:00:01 with 0 errors on Thu Apr 30 14:01:23 2026
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
gpt/disk01 ONLINE 0 0 0
gpt/disk00 ONLINE 0 0 0
errors: No known data errors
# df
Filesystem 1K-blocks Used Avail Capacity Mounted on
zroot/ROOT/default 233445744 1594516 231851228 1% /
devfs 1 0 1 0% /dev
/dev/gpt/efiboot0 262128 648 261479 0% /boot/efi
tank 1703384 96 1703288 0% /tank
zroot/tmp 231851324 96 231851228 0% /tmp
zroot/var/log 231851736 508 231851228 0% /var/log
zroot/home 231851324 96 231851228 0% /home
zroot/usr/src 231851324 96 231851228 0% /usr/src
zroot/var/tmp 231851324 96 231851228 0% /var/tmp
zroot/var/crash 231851324 96 231851228 0% /var/crash
zroot/usr/ports 231851324 96 231851228 0% /usr/ports
zroot/var/audit 231851324 96 231851228 0% /var/audit
zroot/var/mail 231851400 172 231851228 0% /var/mail
zroot 231851324 96 231851228 0% /zroot
gptラベルでミラーリング構成しているのでUSBポートを差し替えても正常にミラーリングが構成されてマウント(/tank)されています。
以上でZFSでミラーリング構成を行い、ミラーリングディスクの交換方法、ミラーリングの止め方、外部ディスクのマウント/アンマウント等一通り紹介できたかと思います。
あくまでも自分用のまとめですが、FreeBSDのZFSで困っている人がいたら参考になれば幸いです。
