# 機能設計書 12-ZFS

## 概要

本ドキュメントは、FreeBSDに統合されたZettabyte File System（ZFS）の機能設計を記載する。ZFSはストレージプール管理、データ整合性保証、スナップショット、クローン、RAID-Z、圧縮、重複排除など高度な機能を統合したファイルシステムである。

### 本機能の処理概要

**業務上の目的・背景**：ZFSは従来のファイルシステム+ボリュームマネージャという分離構造を統合し、単一のストレージスタックで高信頼性・高機能なデータ管理を実現する。チェックサムベースのデータ整合性検証、Copy-On-Write（COW）による安全な更新、スナップショットによるポイントインタイムリカバリが主要な課題解決ポイントである。

**機能の利用シーン**：サーバのデータストレージ、ルートファイルシステム（ZFS Boot Environment）、NASストレージ、仮想マシンストレージなど。bsdinstallではZFSブート設定画面（画面No.16）にて対話的にZFSプールを構成できる。

**主要な処理内容**：
1. ストレージプール（zpool）の作成・管理・インポート・エクスポート
2. データセット（ファイルシステム・ボリューム・スナップショット）の管理
3. Copy-On-Write（COW）によるデータ更新
4. チェックサムによるデータ整合性検証（fletcher4, SHA-256等）
5. RAID-Z（RAID-Z1/Z2/Z3）、ミラー等の冗長化
6. 透過的データ圧縮（LZ4, GZIP, ZSTD等）
7. スナップショット・クローン・ブックマーク
8. send/receiveによるレプリケーション
9. ARC（Adaptive Replacement Cache）によるキャッシュ管理
10. Boot Environment管理

**関連システム・外部連携**：GEOMストレージフレームワーク経由でディスクにアクセス。ZFS Boot Environmentはブートローダ（loader）と連携する。GEOM ELI暗号化との組み合わせも可能。

**権限による制御**：zpoolおよびzfsコマンドの実行にはroot権限が必要（委任管理を除く）。データセット単位でのプロパティ設定によりマウントポイント、クォータ、予約容量等を制御。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 15 | パーティションモード選択画面 | 遷移先機能 | ZFS選択時のzfsboot画面への遷移 |
| 16 | ZFSブート設定画面 | 主機能 | ZFSプール名・vdevタイプ・暗号化・スワップサイズ・ディスク選択等の対話的設定 |
| 17 | 手動パーティション編集画面 | 補助機能 | ZFSパーティションの作成オプション |

## 機能種別

CRUD操作 / ストレージ管理 / データ整合性保証 / レプリケーション

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| プール名 | char* | Yes | zpoolの名前 | 英数字・アンダースコア |
| vdevスペック | char*[] | Yes | ディスクデバイスのリスト | デバイスの存在確認 |
| vdevタイプ | enum | No | mirror, raidz, raidz2, raidz3, stripe | 有効なタイプ |
| データセット名 | char* | Yes | pool/dataset形式の名前 | パス形式の妥当性 |
| プロパティ | nvlist_t | No | compression, quota等のプロパティ | プロパティ名と値の妥当性 |

### 入力データソース

- zpool(8) / zfs(8) コマンドからのユーザ入力
- ディスクデバイス（GEOMプロバイダ経由）
- zpoolラベル情報（ディスク上のメタデータ）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ファイルデータ | バイトストリーム | 読み取り要求に対するファイル内容 |
| プール状態 | zpool_status_t | プールの健全性状態 |
| データセットプロパティ | nvlist_t | データセットのプロパティ値 |
| スナップショットリスト | list | データセットのスナップショット一覧 |

### 出力先

- VFS層を介したユーザ空間アプリケーション
- ARC（Adaptive Replacement Cache）
- ZIL（ZFS Intent Log）

## 処理フロー

### 処理シーケンス

```
1. プール作成（zpool create）
   └─ vdev構成検証 → ラベル書き込み → uberblock初期化 → MOS作成
2. マウント処理（zfs_mount）
   └─ プールインポート → データセットマウント → VFS登録
3. ファイルI/O
   └─ ZPL → DMU → ARC/ZIL → SPA → vdev → ディスクI/O
4. スナップショット作成
   └─ TXG（トランザクショングループ）境界でスナップショットポイント記録
5. scrub/resilver
   └─ 全ブロックのチェックサム検証・冗長コピーからの修復
```

### フローチャート

```mermaid
flowchart TD
    A[I/O要求] --> B[ZPL - ZFS POSIX Layer]
    B --> C[DMU - Data Management Unit]
    C --> D[ARC - Adaptive Replacement Cache]
    D --> E{キャッシュヒット?}
    E -->|Yes| F[データ返却]
    E -->|No| G[SPA - Storage Pool Allocator]
    G --> H[vdev層]
    H --> I[ディスクI/O]
    I --> J[チェックサム検証]
    J --> F
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-12-01 | COW更新 | データの上書きは行わず、常に新しい位置に書き込む（Copy-On-Write） | 全書き込み時 |
| BR-12-02 | チェックサム検証 | 全データブロックにチェックサムを付与し、読み取り時に検証 | 全読み取り時 |
| BR-12-03 | TXGコミット | トランザクショングループ単位で一括コミット（デフォルト5秒間隔） | 書き込み時 |
| BR-12-04 | RAID-Z冗長性 | RAID-Z1は1台、Z2は2台、Z3は3台のディスク障害に耐える | vdev構成時 |

### 計算ロジック

- 使用可能容量 = プール総容量 - メタデータ - スラップスペース予約（通常3.2%）
- RAID-Z有効容量 = (ディスク数 - パリティ数) * 最小ディスク容量

## データベース操作仕様

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| ファイル作成 | ZAP（ZFS Attribute Processor） | INSERT | ディレクトリZAPオブジェクトへのエントリ追加 |
| データ書き込み | DMUオブジェクト | INSERT/UPDATE | COWによる新規ブロック書き込み |
| スナップショット | DSLデータセット | INSERT | スナップショットデータセットの作成 |

### テーブル別操作詳細

#### MOS（Meta Object Set）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | object directory | プール構成情報取得 | プールインポート時 |
| UPDATE | space map | ブロック割り当て情報更新 | 書き込み時 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ENOSPC | リソース不足 | プールの空き容量不足 | ディスク追加またはスナップショット削除 |
| ECKSUM | チェックサムエラー | データ破損検出 | scrubによる自動修復（冗長構成時） |
| EBUSY | リソース使用中 | アンマウント時にファイルが開かれている | プロセス終了後に再試行 |
| DEGRADED | プール劣化 | ディスク障害 | 障害ディスク交換とresilver |

### リトライ仕様

チェックサムエラー検出時、冗長コピー（ミラーまたはRAID-Zパリティ）が存在する場合は自動的に正常コピーから読み取りを行う。

## トランザクション仕様

ZFSはトランザクショングループ（TXG）単位でアトミックなコミットを行う。各TXGは「open」→「quiescing」→「syncing」の3段階を経て書き込まれる。ZIL（ZFS Intent Log）により、同期書き込み要求はTXGコミット前でもディスクに永続化される。

## パフォーマンス要件

- ARC（Adaptive Replacement Cache）による高効率キャッシュ（L1）
- L2ARC（SSD等の高速デバイスを使用したセカンダリキャッシュ）
- SLOG（Separate Log Device）による同期書き込み高速化
- LZ4圧縮によるスループット向上（圧縮可能データの場合）
- メタデータ特別割り当て（Special VDEV）による小ブロックI/O高速化

## セキュリティ考慮事項

- データセット暗号化（aes-256-gcm等）のネイティブサポート
- GEOM ELI暗号化との組み合わせによるディスク全体暗号化
- delegated administratorによる非root権限でのデータセット管理
- ACLサポート（NFSv4 ACL）

## 備考

- FreeBSDのZFS実装はOpenZFSプロジェクトベース（sys/contrib/openzfs/）
- ZFSはCDDLライセンスで提供される
- ZFS Boot Environmentにより、OS更新前後のブート環境切り替えが可能

---

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

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

### 推奨読解順序

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

ZFSの階層的なデータモデル（SPA → DMU → ZPL）を理解することが最重要である。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | spa.h | `sys/contrib/openzfs/include/sys/spa.h` | ストレージプール構造体（spa_t） |
| 1-2 | dmu.h | `sys/contrib/openzfs/include/sys/dmu.h` | DMUオブジェクトタイプ定義 |
| 1-3 | zfs_znode.h | `sys/contrib/openzfs/include/sys/zfs_znode.h` | znodeクラス（ZFS版inode） |
| 1-4 | zap.h | `sys/contrib/openzfs/include/sys/zap.h` | ZFS Attribute Processor構造 |

**読解のコツ**: ZFSは多層アーキテクチャ（ZPL→DMU→SPA→vdev）で構成されている。各層は明確なインタフェースで分離されており、上位層から順に読み進めると理解しやすい。

#### Step 2: エントリーポイントを理解する（VFS操作）

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | zfs_vfsops.c | `sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vfsops.c` | FreeBSD向けVFS操作実装 |

**主要処理フロー**:
1. **124-126行目**: zfs_mount/zfs_umount/zfs_root の宣言
2. **136-139行目**: vfsops構造体の登録
3. **1364行目**: zfs_mount() - マウント処理
4. **1564行目**: zfs_root() - ルートvnode取得
5. **1725行目**: zfs_umount() - アンマウント処理

#### Step 3: vnode操作を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | zfs_vnops.c | `sys/contrib/openzfs/module/zfs/zfs_vnops.c` | ZFS vnode操作（プラットフォーム共通） |

#### Step 4: DMU層を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | dmu.c | `sys/contrib/openzfs/module/zfs/dmu.c` | Data Management Unit - オブジェクトレベルのI/O |

#### Step 5: SPA層を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | spa.c | `sys/contrib/openzfs/module/zfs/spa.c` | Storage Pool Allocator - プール管理の中核 |

#### Step 6: ARC（キャッシュ）を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 6-1 | arc.c | `sys/contrib/openzfs/module/zfs/arc.c` | Adaptive Replacement Cache実装 |

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

```
VFS層
    │
    ├─ ZPL（ZFS POSIX Layer）
    │      ├─ zfs_vfsops.c（mount/unmount）
    │      └─ zfs_vnops.c（create/read/write/remove）
    │
    ├─ DMU（Data Management Unit）
    │      ├─ dmu.c（オブジェクトI/O）
    │      ├─ dmu_tx.c（トランザクション管理）
    │      └─ dnode.c（dnodeオブジェクト管理）
    │
    ├─ SPA（Storage Pool Allocator）
    │      ├─ spa.c（プール管理）
    │      ├─ metaslab.c（ブロック割り当て）
    │      └─ txg.c（トランザクショングループ）
    │
    ├─ ARC（キャッシュ）
    │      └─ arc.c
    │
    ├─ ZIL（Intent Log）
    │      └─ zil.c
    │
    └─ vdev層
           ├─ vdev.c（仮想デバイス管理）
           ├─ vdev_raidz.c（RAID-Z）
           └─ vdev_mirror.c（ミラー）
```

### データフロー図

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

ユーザI/O要求    ───────▶  ZPL（POSIX変換）            ───▶ ファイルデータ
                           ↓
                           DMU（オブジェクトI/O）
                           ↓
                           ARC（キャッシュ判定）
                           ↓（キャッシュミス時）
                           SPA（プールI/O）
                           ↓
                           vdev（デバイスI/O + チェックサム検証）
                           ↓
                           GEOMプロバイダ → ディスク
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| zfs_vfsops.c | `sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vfsops.c` | ソース | FreeBSD VFS操作 |
| zfs_vnops.c | `sys/contrib/openzfs/module/zfs/zfs_vnops.c` | ソース | vnode操作（共通） |
| zfs_znode.c | `sys/contrib/openzfs/module/zfs/zfs_znode.c` | ソース | znode管理 |
| dmu.c | `sys/contrib/openzfs/module/zfs/dmu.c` | ソース | Data Management Unit |
| spa.c | `sys/contrib/openzfs/module/zfs/spa.c` | ソース | Storage Pool Allocator |
| arc.c | `sys/contrib/openzfs/module/zfs/arc.c` | ソース | Adaptive Replacement Cache |
| zil.c | `sys/contrib/openzfs/module/zfs/zil.c` | ソース | ZFS Intent Log |
| zvol.c | `sys/contrib/openzfs/module/zfs/zvol.c` | ソース | ZFSボリューム |
| vdev.c | `sys/contrib/openzfs/module/zfs/vdev.c` | ソース | 仮想デバイス管理 |
| vdev_raidz.c | `sys/contrib/openzfs/module/zfs/vdev_raidz.c` | ソース | RAID-Z実装 |
| metaslab.c | `sys/contrib/openzfs/module/zfs/metaslab.c` | ソース | メタスラブ（ブロック割り当て） |
| txg.c | `sys/contrib/openzfs/module/zfs/txg.c` | ソース | トランザクショングループ |
| dsl_pool.c | `sys/contrib/openzfs/module/zfs/dsl_pool.c` | ソース | DSLプール管理 |
| dsl_crypt.c | `sys/contrib/openzfs/module/zfs/dsl_crypt.c` | ソース | データセット暗号化 |
| zfsbootcfg | `sbin/zfsbootcfg/` | ソース | ZFSブート設定ツール |
