# 機能設計書 26-GEOMストレージフレームワーク

## 概要

本ドキュメントは、FreeBSDのGEOMストレージフレームワークの機能設計を記述する。GEOMはディスクI/O変換のモジュラーフレームワークであり、パーティション管理、RAID、暗号化等のストレージ変換をクラスとして実装し、階層的に組み合わせることができる。

### 本機能の処理概要

**業務上の目的・背景**：ストレージデバイスへのI/Oパスにおいて、パーティショニング、ミラーリング、暗号化、圧縮等の変換処理をモジュラーに組み合わせる必要がある。GEOMフレームワークはこれらの変換をクラス（class）として定義し、プロバイダ（provider）とコンシューマ（consumer）のグラフ構造で接続することで、柔軟なストレージスタックの構築を可能にする。DARPA/SPAWAR契約の下、NAI Labsと共同で開発された。

**機能の利用シーン**：ディスクパーティション管理、ソフトウェアRAID構成、ディスク暗号化、ストレージデバイスの仮想化・変換。

**主要な処理内容**：
1. GEOMクラスの登録・管理（g_class構造体）
2. GEOMジオメトリの作成・破棄（g_geom構造体）
3. プロバイダとコンシューマの接続管理
4. BIOリクエストの変換・転送（g_start）
5. taste機構によるデバイス自動認識
6. イベントシステムによる非同期処理
7. ctl（制御）インタフェースによるユーザ空間からの操作

**関連システム・外部連携**：CAMストレージサブシステム（下位層）、VFSファイルシステム（上位層）、sbin/geom（ユーザランドツール）

**権限による制御**：GEOM制御操作にはroot権限が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 15 | パーティションモード選択画面 | 主機能 | Auto(ZFS)/Auto(UFS)/Manual/Shellの4方式からパーティションモードを選択 |
| 16 | ZFSブート設定画面 | 補助機能 | ディスクパーティションスキーム（GPT等）の設定 |
| 17 | 手動パーティション編集画面 | 主機能 | GEOMベースのディスクパーティション手動作成・編集 |

## 機能種別

ストレージI/O変換フレームワーク / デバイス管理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| bio | struct bio* | Yes | I/Oリクエスト（読み/書き/削除） | bio_cmd検証 |
| gctl_req | struct gctl_req* | No | ユーザ空間からの制御リクエスト | パラメータ検証 |

### 入力データソース

- ファイルシステム/VFS層からのBIOリクエスト
- sbin/geomコマンドからのgctl制御リクエスト
- デバイスドライバからのプロバイダ登録

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| g_provider | struct g_provider* | ストレージプロバイダ（上位層に公開） |
| bio | struct bio* | 変換済みI/Oリクエスト（下位層に転送） |

### 出力先

- 下位層のGEOMコンシューマまたはデバイスドライバ
- 上位層のVFS/ファイルシステム

## 処理フロー

### 処理シーケンス

```
1. GEOMクラス登録
   └─ g_class構造体の定義・DECLARE_GEOM_CLASSマクロ
      ├─ taste関数: 新規プロバイダの自動認識
      ├─ ctlreq関数: ユーザ空間制御リクエスト処理
      └─ start関数: BIOリクエスト処理
2. プロバイダ出現時
   └─ 各クラスのtaste()呼び出し
      ├─ メタデータ読み込み・検証
      └─ マッチ時: geom作成、consumer/provider接続
3. I/Oリクエスト処理
   └─ g_start(bio) → クラスのstart()
      ├─ BIO変換（オフセット調整、分割、暗号化等）
      └─ g_io_request() → 下位層へ転送
4. I/O完了
   └─ g_io_deliver() → 上位層へ通知
```

### フローチャート

```mermaid
flowchart TD
    A[VFS/ファイルシステム] --> B[g_provider]
    B --> C[g_start: BIOリクエスト]
    C --> D{GEOMクラスの処理}
    D --> E[BIO変換]
    E --> F[g_io_request]
    F --> G[g_consumer]
    G --> H[下位GEOMクラスまたはデバイスドライバ]
    H --> I[I/O完了]
    I --> J[g_io_deliver]
    J --> K[上位層に完了通知]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-26-01 | taste自動認識 | 新規プロバイダ出現時に全登録クラスのtaste()を呼び出し | G_TF_NORMAL/G_TF_INSIST/G_TF_TRANSPARENT |
| BR-26-02 | アクセスカウント | provider/consumerのアクセス(read/write/exclusive)をカウント管理 | g_access() |
| BR-26-03 | orphan通知 | プロバイダが消滅した場合、接続されたコンシューマにorphan通知 | デバイス取り外し時 |
| BR-26-04 | spoiled通知 | プロバイダのメタデータが変更された場合のコンシューマ通知 | メタデータ更新時 |

### 計算ロジック

特になし。I/Oオフセット変換は各GEOMクラスの実装に依存。

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

本機能はカーネル内フレームワークであり、RDBMS操作は行わない。

| 操作 | 対象データ構造 | 操作種別 | 概要 |
|-----|-------------|---------|------|
| クラス登録 | g_class | CREATE | GEOMクラスのカーネル登録 |
| geom作成 | g_geom | CREATE/DELETE | GEOMインスタンスの作成・破棄 |
| I/O処理 | bio | READ/WRITE | BIOリクエストの変換・転送 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ENXIO | デバイスなし | プロバイダが消滅（orphan） | 上位層にエラー通知 |
| EPERM | 権限不足 | 排他アクセス違反 | アクセスカウントを確認 |
| EIO | I/Oエラー | 下位層からのI/Oエラー | エラーをBIOで上位層に伝播 |

### リトライ仕様

各GEOMクラスの実装に依存（例: ミラークラスはフェイルオーバー）。

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

GEOMトポロジはsx_lockで保護。BIO処理は非同期・ロックフリーで実行。

## パフォーマンス要件

ゼロコピーI/Oパスを目指す設計。BIO変換のオーバーヘッドは各クラスの実装に依存。統計情報（g_stat）によるI/Oパフォーマンス監視。

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

- GEOM制御操作はgctl経由でroot権限を要求
- ELIクラスによるディスク暗号化サポート
- アクセスカウントによる排他制御

## 備考

- DARPA/SPAWAR契約N66001-01-C-8035（CBOSSプロジェクト）の下で開発
- sbin/geomおよびlib/geomにユーザランドツール群
- 多数のサブクラス: cache, concat, eli, gate, journal, label, linux_lvm, mirror, mountver, multipath, nop, part, raid, raid3, shsec, stripe, union, uzip

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | geom.h | `sys/geom/geom.h` | g_class（93行目以降）、g_geom、g_consumer、g_providerの4つの基本構造体。各種コールバック型定義（62-84行目） |

**読解のコツ**: GEOMの基本は「クラス→ジオメトリ→プロバイダ/コンシューマ」の階層。g_classはtaste/start/ctlreqなどのメソッドテーブル。プロバイダは上位層に公開するデバイス、コンシューマは下位層のプロバイダに接続するハンドル。

#### Step 2: カーネルコア実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | geom_kern.c | `sys/geom/geom_kern.c` | GEOMカーネル初期化、イベントスレッド |
| 2-2 | geom_subr.c | `sys/geom/geom_subr.c` | geom/provider/consumer作成・破棄のユーティリティ |
| 2-3 | geom_io.c | `sys/geom/geom_io.c` | BIO I/O処理（g_io_request, g_io_deliver） |
| 2-4 | geom_event.c | `sys/geom/geom_event.c` | イベントシステム |

#### Step 3: 制御インタフェースを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | geom_ctl.c | `sys/geom/geom_ctl.c` | gctl制御リクエスト処理 |
| 3-2 | geom_dev.c | `sys/geom/geom_dev.c` | /devデバイスノード作成 |
| 3-3 | geom_disk.c | `sys/geom/geom_disk.c` | ディスクデバイスのGEOMプロバイダ化 |

#### Step 4: VFS統合を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | geom_vfs.c | `sys/geom/geom_vfs.c` | VFSからのGEOM利用インタフェース |

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

```
VFS / ファイルシステム
    │
    ├─ g_vfs_open() [geom_vfs.c]
    │       └─ g_access()
    │
    ├─ bread/bwrite → g_io_request() [geom_io.c]
    │       └─ class->start(bio) [各クラス]
    │               ├─ BIO変換
    │               └─ g_io_request() → 下位層
    │
    └─ g_vfs_close() [geom_vfs.c]

デバイスドライバ
    │
    ├─ disk_create() → g_disk_create() [geom_disk.c]
    │       └─ g_new_providerf() [geom_subr.c]
    │               └─ taste通知 → 各クラスのtaste()
    │
    └─ I/O完了 → g_io_deliver() [geom_io.c]
            └─ 上位層のBIO完了コールバック

sbin/geom (ユーザ空間)
    │
    └─ gctl ioctl → geom_ctl.c
            └─ class->ctlreq()
```

### データフロー図

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

ファイルシステムI/O ───▶ g_io_request()           ───▶ 変換済みBIO
(BIOリクエスト)           (GEOMスタック通過)              (デバイスドライバへ)

デバイス接続         ───▶ taste()                  ───▶ geom/provider作成
(新規プロバイダ)          (自動認識)                     (/devノード)

gctl制御            ───▶ ctlreq()                 ───▶ 構成変更
(ユーザ空間コマンド)       (制御処理)                     (GEOMトポロジ更新)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| geom.h | `sys/geom/geom.h` | ヘッダ | 基本データ構造・型定義 |
| geom_int.h | `sys/geom/geom_int.h` | ヘッダ | カーネル内部定義 |
| geom_ctl.h | `sys/geom/geom_ctl.h` | ヘッダ | 制御インタフェース定義 |
| geom_disk.h | `sys/geom/geom_disk.h` | ヘッダ | ディスクインタフェース |
| geom_vfs.h | `sys/geom/geom_vfs.h` | ヘッダ | VFS統合インタフェース |
| geom_kern.c | `sys/geom/geom_kern.c` | ソース | カーネル初期化 |
| geom_subr.c | `sys/geom/geom_subr.c` | ソース | ユーティリティ関数 |
| geom_io.c | `sys/geom/geom_io.c` | ソース | BIO I/O処理 |
| geom_event.c | `sys/geom/geom_event.c` | ソース | イベントシステム |
| geom_ctl.c | `sys/geom/geom_ctl.c` | ソース | gctl制御処理 |
| geom_dev.c | `sys/geom/geom_dev.c` | ソース | デバイスノード管理 |
| geom_disk.c | `sys/geom/geom_disk.c` | ソース | ディスクプロバイダ |
| geom_vfs.c | `sys/geom/geom_vfs.c` | ソース | VFS統合 |
| geom_dump.c | `sys/geom/geom_dump.c` | ソース | デバッグダンプ |
| geom_slice.c | `sys/geom/geom_slice.c` | ソース | スライス管理 |
