# 画面設計書 16-ZFSブート設定画面

## 概要

本ドキュメントは、FreeBSD bsdinstallインストーラにおけるZFSブート設定画面の設計書である。ZFSプールの各種オプション（プール名、vdevタイプ、暗号化、スワップサイズ、ディスク選択等）を対話的に設定する画面について記述する。

### 本画面の処理概要

この画面では、ZFSルートプールの作成に必要な全ての設定を対話的に行う。メインメニューから各設定項目にアクセスし、最終的にInstallを選択することでディスクパーティションの作成とZFSプールの構築が実行される。

**業務上の目的・背景**：ZFSはFreeBSDにおいて推奨されるファイルシステムであり、スナップショット、圧縮、ミラーリング、RAID-Z等の高度な機能を提供する。本画面はZFSのブートプール作成に必要な各種パラメータを一元的に設定する画面であり、ユーザがディスク構成やセキュリティ要件に応じて柔軟にカスタマイズできるようになっている。

**画面へのアクセス方法**：パーティションモード選択画面（No.15）で「Auto (ZFS)」を選択した場合に遷移する。`bsdinstall zfsboot` コマンドで呼び出される。

**主要な操作・処理内容**：
1. メインメニューでZFSプールの設定オプション一覧を表示する
2. Pool Type/Disks：vdevタイプ（stripe/mirror/raid10/raidz1/raidz2/raidz3）とディスクを選択する
3. Pool Name：プール名を設定する（デフォルト: zroot）
4. Force 4K Sectors：4Kセクタアライメントの有効/無効を切り替える
5. Encrypt Disks：geli(8)によるディスク暗号化の有効/無効を切り替える
6. Partition Scheme：パーティションスキーム（GPT）とブートタイプ（BIOS/UEFI/BIOS+UEFI）を選択する
7. Swap Size：スワップサイズを設定する（デフォルト: 2g）
8. Swap Mirror/Encrypt：スワップのミラーリングと暗号化を切り替える
9. ZFS Pool Options：ZFSプール作成オプションをカスタマイズする
10. Installを選択してディスクパーティション作成とZFSプール構築を実行する

**画面遷移**：
- 遷移元：パーティションモード選択画面（No.15）のAuto ZFS選択
- 遷移先（Install成功）：マウント処理後、インストール実行フローへ進む
- キャンセル時：パーティションモード選択画面に戻る

**権限による表示制御**：権限による表示制御はない。ブートタイプのデフォルトはアーキテクチャとブート方式（UEFI/BIOS）により自動決定される。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 12 | ZFS | 主機能 | ZFSプール名・vdevタイプ・暗号化・スワップサイズ・ディスク選択等の対話的設定 |
| 27 | GEOM ELI（ディスク暗号化） | 補助機能 | ZFSプールのgeli暗号化オプション設定 |
| 26 | GEOMストレージフレームワーク | 補助機能 | ディスクパーティションスキーム（GPT等）の設定 |
| 33 | スワップ管理 | 補助機能 | スワップパーティションサイズの設定 |

## 画面種別

対話型メニュー（複数サブ画面を持つ設定画面）

## URL/ルーティング

TUIベースのbsddialogインターフェース。URLは存在しない。
- 呼び出し：`bsdinstall zfsboot`
- 実体スクリプト：`usr.sbin/bsdinstall/scripts/zfsboot`

## 入出力項目

| 項目名 | 入出力 | 型 | 必須 | 初期値 | 説明 |
|--------|--------|------|------|--------|------|
| Pool Type/Disks | 入力（選択） | メニュー + チェックリスト | はい | stripe, ディスク未選択 | vdevタイプとディスクの選択 |
| Pool Name | 入力 | テキスト | はい | zroot | ZFSプール名 |
| Force 4K Sectors | 入力（トグル） | YES/NO | いいえ | YES | 4Kセクタアライメント |
| Encrypt Disks | 入力（トグル） | YES/NO | いいえ | NO | geli暗号化 |
| Partition Scheme | 入力（トグル） | 選択 | いいえ | GPT (BIOS/UEFI/BIOS+UEFI) | パーティションスキームとブートタイプ |
| Swap Size | 入力 | テキスト（SI単位） | いいえ | 2g | スワップサイズ |
| Swap Mirror | 入力（トグル） | YES/NO | いいえ | NO | スワップミラーリング |
| Swap Encrypt | 入力（トグル） | YES/NO | いいえ | NO | スワップ暗号化 |
| ZFS Pool Options | 入力 | テキスト | いいえ | -O compression=on -O atime=off | プール作成オプション |

## 表示項目

| 項目名 | 表示位置 | 説明 |
|--------|----------|------|
| バックタイトル | 画面上部 | "$OSNAME Installer" |
| タイトル | ダイアログタイトル | "ZFS Configuration" |
| メニュー説明 | メニュー上部 | "Configure Options:" |
| Install | メニュー項目 | "Proceed with Installation" |
| Pool Type/Disks | メニュー項目 | 現在のvdevタイプとディスク数を表示 |
| Rescan Devices | メニュー項目 | デバイス再スキャン |
| Disk Info | メニュー項目 | ディスク詳細情報表示 |
| 各設定項目 | メニュー項目 | 現在値を右側に表示 |

## イベント仕様

### 1-Install選択

1. プール名が空でないことを確認する（行1577-1580）
2. `dialog_menu_layout`でディスク選択とvdevタイプの妥当性を確認する（行1586）
3. 各ディスクのサイズがスワップ＋ブートプール分以上あることを確認する（行1589-1621）
4. 「Last Chance」確認ダイアログでディスク消去の最終確認を行う（行1627）
5. `zfs_create_boot`でディスクパーティション作成・ZFSプール構築を実行する（行1639-1640）
6. 成功時にZFSBOOT_DISKSをファイルに保存して終了する（行1643）

### 2-Pool Type/Disks選択

1. vdevタイプ選択メニューを表示する（stripe/mirror/raid10/raidz1/raidz2/raidz3）
2. ディスクチェックリストを表示し、使用するディスクを選択する
3. 選択ディスク数がvdevタイプの最小要件を満たしているか確認する

### 3-各設定項目の変更

各設定項目はトグルまたはテキスト入力で値を変更する。変更は即座にメニュー表示に反映される。

### 4-Cancel

cancel選択でスクリプトが終了（f_die）し、パーティションモード選択画面に戻る。

## データベース更新仕様

### 操作別データベース影響一覧

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| Install実行 | $BSDINSTALL_TMPETC/fstab | WRITE | fstab初期化・スワップエントリ書き込み |
| Install実行 | $BSDINSTALL_TMPETC/rc.conf.zfs | WRITE | zfs_enable="YES" |
| Install実行 | $BSDINSTALL_TMPBOOT/loader.conf.* | WRITE | 各種loader.confエントリ |
| Install実行 | ZFSプール | CREATE | zpool create + zfs create |
| Install実行 | ディスクパーティション | CREATE | gpart create/add |

### テーブル別更新項目詳細

#### fstab

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| WRITE | ESPエントリ | /dev/gpt/efiboot0 /boot/efi msdosfs rw 2 2 | UEFI有効時 |
| WRITE | スワップエントリ | /dev/{disk}{swappart} none swap sw 0 0 | スワップ有効時 |

#### rc.conf.zfs

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| APPEND | zfs_enable | "YES" | 常に設定 |

## メッセージ仕様

| 種別 | 条件 | メッセージ |
|------|------|-----------|
| エラー | プール名空 | "Pool name cannot be empty." |
| エラー | ディスク未選択 | "No disks selected." |
| エラー | ディスク不足 | "Not enough disks selected. ({n} < {min} minimum)" |
| エラー | ディスク容量不足 | スワップ/ブートプールサイズがディスク容量を超過 |
| 確認 | Install前 | "Last Chance! Are you sure you want to destroy the current contents of the following disks: {ディスク一覧}" |
| 入力 | geli暗号化 | "Enter a strong passphrase, used to protect your encryption keys." |
| 情報 | geli初期化中 | "Initializing encryption on selected disks, this will take several seconds per disk" |

## 例外処理

| 条件 | 動作 |
|------|------|
| プール名空 | エラーメッセージ表示、メニューに戻る |
| ディスク不足 | 「Change Selection」でディスク選択に戻るか「Cancel」で終了 |
| ディスク容量不足 | エラーメッセージ表示、メニューに戻る |
| Last Chance拒否 | メニューに戻る |
| geli初期化失敗 | 非対話時はf_die、対話時はFAILURE返却 |
| ZFSプール作成失敗 | メニューに戻って再試行 |

## 備考

- デフォルトのZFSデータセットレイアウトは `/ROOT/default`（ブート環境対応）、`/home`、`/tmp`、`/usr`、`/usr/ports`、`/usr/src`、`/var` 等を含む（行145-176）
- arm64/riscvではUEFIブートのみがサポートされる（行1535-1538）
- ブート方式はmachdep.bootmethod sysctlから自動検出される（行1542-1543）
- プール名が既存プールと重複する場合、名前変更ダイアログが表示される（行1521-1529）
- RAID-10はstripeされたミラーとして実装される（行1267-1278）
- 暗号化有効時は自動的にブートプールが有効化される

---

## コードリーディングガイド

本画面を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | zfsboot | `usr.sbin/bsdinstall/scripts/zfsboot` | 行39-183の設定変数（ZFSBOOT_*）とデフォルト値を理解する。特にZFSBOOT_DATASETS（行145-176）のデータセットレイアウトが重要 |
| 1-2 | zfsboot | `usr.sbin/bsdinstall/scripts/zfsboot` | 行184-238のグローバル定数（コマンドテンプレート文字列）を把握する |

**読解のコツ**: ZFSBOOT_*変数は `: ${VAR:=default}` 形式で宣言され、外部からの上書きが可能。コマンドテンプレートはprintf形式でf_eval_catchから呼び出される。

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | zfsboot | `usr.sbin/bsdinstall/scripts/zfsboot` | 行1503-1751のMAINセクション。メインメニューループとInstall処理の流れを理解する |

**主要処理フロー**:
1. **行1508-1509**: ダイアログタイトル設定
2. **行1521-1529**: 既存プール名の重複チェック
3. **行1534-1552**: ブートタイプのデフォルト決定（アーキテクチャ＋ブート方式）
4. **行1557-1749**: メインメニューループ（dialog_menu_main呼び出し＋case分岐）

#### Step 3: ZFSプール作成処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | zfsboot | `usr.sbin/bsdinstall/scripts/zfsboot` | 行1018-1452の`zfs_create_boot`関数。ディスクパーティション作成からZFSプール構築までの一連の処理 |
| 3-2 | zfsboot | `usr.sbin/bsdinstall/scripts/zfsboot` | 行761-1011の`zfs_create_diskpart`関数。個々のディスクのパーティション作成処理 |

### プログラム呼び出し階層図

```
bsdinstall zfsboot (usr.sbin/bsdinstall/scripts/zfsboot)
    |
    +-- dialog_menu_main() (行338-416) - メインメニュー表示
    |      |
    |      +-- [Install] --> dialog_menu_layout() --> dialog_last_chance()
    |      |                      --> zfs_create_boot()
    |      |                             +-- zfs_create_diskpart() (各ディスク)
    |      |                             +-- geli初期化 (暗号化時)
    |      |                             +-- zpool create
    |      |                             +-- zfs create (データセット群)
    |      |
    |      +-- [Pool Type/Disks] --> dialog_menu_layout()
    |      +-- [Pool Name] --> f_dialog_input
    |      +-- [Swap Size] --> f_dialog_input
    |      +-- [Disk Info] --> dialog_menu_diskinfo()
    |      +-- [トグル項目] --> 変数切り替え
    |
    +-- f_device_find / f_device_sort_by (ディスク列挙)
```

### データフロー図

```
[入力]                       [処理]                          [出力]

ZFSBOOT_* 環境変数 -------> 初期値設定 -------> メニュー表示
                                                      |
ユーザ設定変更 -----------> メニューループ -----> ZFSBOOT_*変数更新
                                                      |
[Install選択]                                         v
                                               zfs_create_boot()
                                                      |
                                                      +-> gpart create/add
                                                      +-> zpool create
                                                      +-> zfs create
                                                      +-> fstab書き込み
                                                      +-> rc.conf/loader.conf書き込み
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| zfsboot | `usr.sbin/bsdinstall/scripts/zfsboot` | ソース | ZFSブート設定のメインスクリプト（1756行） |
| auto | `usr.sbin/bsdinstall/scripts/auto` | ソース | zfsbootの呼び出し元 |
| common.subr | `/usr/share/bsdconfig/common.subr` | ライブラリ | 共通サブルーチン |
| device.subr | `/usr/share/bsdconfig/device.subr` | ライブラリ | デバイス列挙・操作 |
| dialog.subr | `/usr/share/bsdconfig/dialog.subr` | ライブラリ | ダイアログ操作 |
| password.subr | `/usr/share/bsdconfig/password/password.subr` | ライブラリ | パスワード入力（geli用） |
| variable.subr | `/usr/share/bsdconfig/variable.subr` | ライブラリ | 変数操作 |
