# 機能設計書 29-GEOMゲートウェイ

## 概要

本ドキュメントは、FreeBSDのGEOMゲートウェイ（ggate）の機能設計を記述する。GEOMゲートウェイはネットワーク経由でブロックデバイスをエクスポートするGEOMクラスであり、リモートのブロックデバイスをローカルに仮想的なディスクとして提供する。

### 本機能の処理概要

**業務上の目的・背景**：リモートサーバ上のブロックデバイスをネットワーク経由でローカルマシンに公開する必要がある。GEOMゲートウェイはカーネル内のGEOMクラスとユーザ空間デーモンの協調動作により、ネットワーク経由のブロックデバイスアクセスを実現する。NBD（Network Block Device）と類似の機能を提供。

**機能の利用シーン**：リモートディスクのネットワーク共有、iSCSI代替のシンプルなブロックデバイス共有、ディスクレスブート環境でのリモートストレージ利用。

**主要な処理内容**：
1. ggateデバイスの作成・管理（/dev/ggateN）
2. カーネルとユーザ空間デーモン間のI/O転送（ioctlベース）
3. リモートI/O処理（ggated: サーバ側デーモン）
4. ローカルI/O処理（ggatec: クライアント側デーモン）
5. 読み取り専用プロバイダの補助読み込み（readprov機能）

**関連システム・外部連携**：GEOMストレージフレームワーク、ネットワークスタック

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | - |

## 機能種別

ストレージネットワーク共有 / デバイス仮想化

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| gctl_mediasize | off_t | Yes | デバイスサイズ | 正の値 |
| gctl_sectorsize | u_int | Yes | セクタサイズ | 2の累乗 |
| gctl_flags | u_int | No | フラグ（READONLY/WRITEONLY） | G_GATE_USERFLAGS |
| gctl_maxcount | u_int | No | 最大キュー数 | 1-G_GATE_MAX_QUEUE_SIZE |
| gctl_timeout | u_int | No | タイムアウト（秒） | 正の値 |
| gctl_name | char[NAME_MAX] | No | プロバイダ名 | NAME_MAX以内 |
| gctl_readprov | char[NAME_MAX] | No | 補助読み込みプロバイダ | 有効なプロバイダ |
| gctl_readoffset | off_t | No | 補助読み込みオフセット | 非負の値 |

### 入力データソース

- ggateユーザ空間コマンド（ggatec/ggated/ggatel）からのioctl
- ネットワーク経由のリモートI/Oデータ

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| provider | g_provider* | ggateデバイス（/dev/ggateN） |
| I/Oデータ | g_gate_ctl_io | I/O結果データ |

### 出力先

- GEOMプロバイダとして上位層に公開
- ioctl経由でユーザ空間デーモンにI/Oリクエストを渡す

## 処理フロー

### 処理シーケンス

```
1. G_GATE_CMD_CREATE（デバイス作成）
   └─ g_gate_softc構造体の初期化
      ├─ キュー初期化（sc_inqueue, sc_outqueue）
      ├─ GEOMプロバイダ作成（/dev/ggateN）
      └─ タイムアウトcallout設定
2. I/Oリクエスト処理
   └─ 上位層からのBIO → sc_inqueueに追加
      ├─ G_GATE_CMD_START: デーモンがI/Oリクエスト取得
      ├─ デーモン: リモートI/O実行
      └─ G_GATE_CMD_DONE: デーモンが結果返却 → sc_outqueue
3. G_GATE_CMD_DESTROY（デバイス破棄）
   └─ G_GATE_FLAG_DESTROY設定 → wakeup → リソース解放
```

### フローチャート

```mermaid
flowchart TD
    A[上位層BIO] --> B[sc_inqueueに追加]
    B --> C[デーモンwakeup]
    C --> D[G_GATE_CMD_START: リクエスト取得]
    D --> E[デーモン: リモートI/O実行]
    E --> F[G_GATE_CMD_DONE: 結果返却]
    F --> G[sc_outqueueから結果取得]
    G --> H[BIO完了: g_io_deliver]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-29-01 | キューサイズ制限 | 最大G_GATE_MAX_QUEUE_SIZE(4096)のリクエストをキューイング | リクエスト追加時 |
| BR-29-02 | ユニット自動割り当て | G_GATE_UNIT_AUTO(-1)で自動ユニット番号割り当て | デバイス作成時 |
| BR-29-03 | 名前指定 | G_GATE_NAME_GIVEN(-2)で任意のプロバイダ名を指定 | デバイス作成時 |
| BR-29-04 | 読み取り専用/書き込み専用 | G_GATE_FLAG_READONLY/WRITEONLYでアクセスモード制御 | デバイス作成時 |
| BR-29-05 | タイムアウト | calloutベースのタイムアウト検出 | I/O処理中 |
| BR-29-06 | シーケンス番号 | sc_seqでI/Oリクエストの順序管理 | I/O処理時 |

### 計算ロジック

特になし。I/Oオフセット・長さはそのままリモートに転送。

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

本機能はカーネル内デバイス仮想化であり、RDBMS操作は行わない。

| 操作 | 対象データ構造 | 操作種別 | 概要 |
|-----|-------------|---------|------|
| デバイス作成 | g_gate_softc | CREATE | ggateデバイスの初期化 |
| I/O転送 | g_gate_ctl_io | READ/WRITE | ioctl経由のI/Oデータ転送 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ENOMEM | メモリ不足 | キューオーバーフロー | maxcountパラメータ調整 |
| ETIMEDOUT | タイムアウト | デーモン応答遅延 | ネットワーク/デーモン確認 |
| ENXIO | デバイスなし | ggateデバイス未作成 | デバイス作成確認 |

### リトライ仕様

タイムアウト後のリトライはユーザ空間デーモン側の実装に依存。

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

sc_queue_mtx（mutex）でキュー操作を排他制御。シーケンス番号でI/Oリクエストの順序を保証。

## パフォーマンス要件

ネットワーク遅延に大きく依存。キューサイズ（最大4096）で同時I/O数を制御。補助読み込みプロバイダ（readprov）によりローカルキャッシュ的な読み込み高速化が可能。

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

- /dev/ggctl デバイスのアクセス制御
- ネットワーク経由のデータは暗号化されない（別途SSH等でトンネリングが必要）

## 備考

- G_GATE_VERSION = 3
- ggatec: クライアント側デーモン、ggated: サーバ側デーモン、ggatel: ローカルプロバイダ
- G_GATE_INFOSIZE = 2048バイトのデバイス情報文字列

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | g_gate.h | `sys/geom/gate/g_gate.h` | g_gate_softc（79-101行目）カーネルデバイス管理、g_gate_ctl_create（109-121行目）作成パラメータ、g_gate_ctl_io（151-160行目）I/Oデータ転送、ioctlコマンド定義（66-71行目） |

**読解のコツ**: g_gate_softcのsc_inqueue（着信キュー）とsc_outqueue（完了キュー）が処理の中心。sc_queue_mtxでキュー操作を保護。sc_seqでI/Oの順序を追跡。

#### Step 2: カーネルGEOMクラス実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | g_gate.c | `sys/geom/gate/g_gate.c` | GEOMクラス登録、ioctl処理（CREATE/MODIFY/DESTROY/CANCEL/START/DONE）、BIO start/orphan |

#### Step 3: ユーザ空間デーモンを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | shared/ | `sys/geom/gate/shared/` | 共通ライブラリ・プロトコル定義 |
| 3-2 | ggatec/ | `sys/geom/gate/ggatec/` | クライアント側デーモン |
| 3-3 | ggated/ | `sys/geom/gate/ggated/` | サーバ側デーモン |
| 3-4 | ggatel/ | `sys/geom/gate/ggatel/` | ローカルプロバイダ |

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

```
ggatec (クライアント側ユーザ空間)
    │
    ├─ ioctl(G_GATE_CMD_CREATE) → g_gate.c: デバイス作成
    │
    ├─ ioctl(G_GATE_CMD_START) → g_gate.c: I/Oリクエスト取得
    │       └─ sc_inqueueからBIO取得
    │
    ├─ ネットワーク経由でggatedにI/O転送
    │
    └─ ioctl(G_GATE_CMD_DONE) → g_gate.c: I/O結果返却
            └─ g_io_deliver(): 上位層に完了通知

ggated (サーバ側ユーザ空間)
    │
    └─ ネットワークでリクエスト受信
            └─ ローカルデバイスI/O実行
            └─ 結果をネットワークで返送

上位層 (VFS/ファイルシステム)
    │
    └─ BIO → g_gate.c: start()
            └─ sc_inqueueにBIO追加
            └─ デーモンwakeup
```

### データフロー図

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

VFS BIOリクエスト    ───▶ sc_inqueue               ───▶ g_gate_ctl_io
                          (カーネルキュー)                 (ioctl経由)
                                                           │
                          ggatec                    ◀──    │
                          (ネットワーク送信)                │
                                │                          │
                                ▼                          │
                          ggated                           │
                          (リモートI/O実行)                 │
                                │                          │
                                ▼                          │
                          ggatec                    ───▶  │
                          (結果受信)                        ▼
                                                    g_io_deliver
                                                    (上位層に完了通知)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| g_gate.h | `sys/geom/gate/g_gate.h` | ヘッダ | データ構造・ioctl・定数定義 |
| g_gate.c | `sys/geom/gate/g_gate.c` | ソース | カーネルGEOMクラス実装 |
| Makefile | `sys/geom/gate/Makefile` | ビルド | ビルド設定 |
| Makefile.inc | `sys/geom/gate/Makefile.inc` | ビルド | 共通ビルド設定 |
| shared/ | `sys/geom/gate/shared/` | ソース | 共通ライブラリ |
| ggatec/ | `sys/geom/gate/ggatec/` | ソース | クライアントデーモン |
| ggated/ | `sys/geom/gate/ggated/` | ソース | サーバデーモン |
| ggatel/ | `sys/geom/gate/ggatel/` | ソース | ローカルプロバイダ |
