# 機能設計書 132-FCボリューム

## 概要

本ドキュメントは、Kubernetes における Fibre Channel (FC) ボリュームプラグインの機能設計を記述する。FC プロトコルを介したSANストレージデバイスを Pod にマウントする機能について定義する。

### 本機能の処理概要

**業務上の目的・背景**：Fibre Channel は高性能なストレージネットワーク (SAN) で広く使用されるプロトコルであり、ミッションクリティカルなワークロードに不可欠である。FC ボリュームプラグインにより、既存の FC SAN インフラを Kubernetes ワークロードから透過的に利用できるようにする。

**機能の利用シーン**：高 I/O パフォーマンスが要求されるデータベースやトランザクション処理システムを Kubernetes 上で運用する場合に、FC SAN 上の LUN を Pod にマウントして使用する。

**主要な処理内容**：
1. WWN (World Wide Name) + LUN または WWID (World Wide Identifier) によるデバイス検索
2. SCSI バスの再スキャンによるデバイス発見
3. マルチパスデバイス（device-mapper）の自動検出と利用
4. ファイルシステムモードおよびブロックデバイスモードでのマウント
5. デバイスの SCSI サブシステムからの削除とクリーンアップ

**関連システム・外部連携**：FC HBA (Host Bus Adapter)、Linux SCSI サブシステム、multipath-tools (device-mapper)、/dev/disk/by-path、/dev/disk/by-id

**権限による制御**：PV/PVC の RBAC に基づくアクセス制御。FC デバイスへのアクセスはノードレベルの権限に依存する。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 本機能は PV/PVC 定義を通じて Kubelet が自動的に実行する |

## 機能種別

ボリュームライフサイクル管理（Attach/Mount/Unmount/Detach）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| targetWWNs | []string | 条件付き | FC ターゲットの WWN リスト | wwids と排他。少なくとも1つ必要 |
| lun | *int32 | 条件付き | Logical Unit Number | targetWWNs 指定時は必須 |
| wwids | []string | 条件付き | World Wide Identifier リスト | targetWWNs と排他 |
| fsType | string | No | ファイルシステムタイプ | ext4, xfs 等 |
| readOnly | bool | No | 読み取り専用フラグ | true/false |

### 入力データソース

- PersistentVolume の `.spec.fc` フィールド
- Volume の `.fc` フィールド

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| devicePath | string | 検出されたデバイスパス（例: /dev/sda, /dev/dm-0） |
| mountPath | string | Pod 内のマウントポイントパス |

### 出力先

- Pod のボリュームマウントパス
- Pod のブロックデバイスパス（ブロックモード時）

## 処理フロー

### 処理シーケンス

```
1. searchDisk（デバイス検索）
   └─ WWN+LUN または WWID に基づきデバイスを検索
2. 1次検索
   └─ /dev/disk/by-path (WWN+LUN) または /dev/disk/by-id (WWID) を探索
3. マルチパス検出
   └─ device-mapper デバイスが見つかればそれを使用
4. SCSI バス再スキャン
   └─ 1次検索で見つからない場合、scsiHostRescan を実行して再検索
5. AttachDisk
   └─ デバイスパスの存在確認
6. MountDevice / SetUp
   └─ ファイルシステムフォーマット・マウント → Pod へのバインドマウント
7. DetachDisk（切断時）
   └─ symlink解決 → マルチパスデバイスフラッシュ → SCSI デバイス削除
```

### フローチャート

```mermaid
flowchart TD
    A[searchDisk開始] --> B{WWN+LUN or WWID?}
    B -->|WWN+LUN| C[/dev/disk/by-path 検索]
    B -->|WWID| D[/dev/disk/by-id 検索]
    C --> E{デバイス発見?}
    D --> E
    E -->|Yes| F{マルチパスデバイスあり?}
    E -->|No| G{再スキャン済み?}
    G -->|No| H[SCSI バス再スキャン]
    H --> C
    G -->|Yes| I[エラー: デバイス未検出]
    F -->|Yes| J[dm-XX デバイスを返却]
    F -->|No| K[rawデバイスを返却]
    J --> L[AttachDisk完了]
    K --> L
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-132-01 | デバイス検索方式 | WWN+LUN 指定時は /dev/disk/by-path、WWID 指定時は /dev/disk/by-id を検索 | 常時 |
| BR-132-02 | マルチパス優先 | マルチパスデバイスが検出された場合、rawデバイスよりも優先して使用 | マルチパス構成時 |
| BR-132-03 | 2フェーズ検索 | 1次検索で見つからない場合のみSCSIバスを再スキャン | デバイス未検出時 |
| BR-132-04 | WWID の空白置換 | WWID 内の空白はアンダースコアに置換 | WWID 指定時 |

### 計算ロジック

- by-path パス: `^(pci-.*-fc|fc)-0x{wwn}-lun-{lun}$` の正規表現パターン
- by-id パス: `scsi-{wwid}` のプレフィックス

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

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

本機能にはデータベース操作はない。全ての操作は OS レベルのデバイス操作である。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | デバイス未検出 | WWN/WWID に一致するデバイスが存在しない | SCSI バス再スキャン後に再試行。見つからなければエラー返却 |
| - | デバイスパス不存在 | 検出されたデバイスパスが存在しない | エラー返却 |
| - | マルチパスフラッシュ失敗 | multipath -f コマンド失敗 | 警告ログ出力後、個別デバイス削除を続行 |
| - | SCSI デバイス削除失敗 | /sys/block/{dev}/device/delete への書き込み失敗 | 警告ログ出力後、他デバイスの削除を続行 |

### リトライ仕様

- デバイス検索: SCSIバス再スキャンを含む2フェーズ検索（自動リトライ1回）

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

FC ボリューム操作は OS レベルの処理であり、トランザクション管理は存在しない。

## パフォーマンス要件

- FC デバイスの検索はローカルファイルシステム（/dev/disk/by-path, /dev/disk/by-id）のスキャンであり、通常は即時完了
- SCSI バス再スキャンはホストの HBA 数に比例する時間を要する

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

- FC ゾーニングはストレージ側で管理され、Kubernetes は関与しない
- SELinux マウントコンテキストを `SELinuxMountReadWriteOncePod` フィーチャーゲートでサポート
- デバイス削除は `/sys/block/{dev}/device/delete` への書き込みによる安全な方法を使用

## 備考

- プラグイン名: `kubernetes.io/fc`
- サポートするアクセスモード: ReadWriteOnce, ReadOnlyMany
- ブロックボリュームモードをサポート

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | fc.go | `pkg/volume/fc/fc.go` | fcDisk 構造体（342-354行目）: wwns, lun, wwids フィールドが FC デバイス識別の中核 |
| 1-2 | fc.go | `pkg/volume/fc/fc.go` | fcDiskMounter（374-383行目）, fcDiskUnmounter（413-418行目）の構造 |

**読解のコツ**: FC デバイスは WWN+LUN または WWID の2種類の識別方法がある。コード中の分岐はこの2方式に対応している。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | fc.go | `pkg/volume/fc/fc.go` | ProbeVolumePlugins()（43-45行目）でプラグイン登録 |
| 2-2 | fc.go | `pkg/volume/fc/fc.go` | NewMounter()（111-114行目）がマウント処理の起点 |
| 2-3 | fc.go | `pkg/volume/fc/fc.go` | getWwnsLunWwids()（510-524行目）でデバイス識別情報を抽出 |

#### Step 3: デバイス検索とAttach/Detach処理

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | fc_util.go | `pkg/volume/fc/fc_util.go` | findDisk()（64-81行目）: WWN+LUNによるby-path検索 |
| 3-2 | fc_util.go | `pkg/volume/fc/fc_util.go` | findDiskWWIDs()（84-113行目）: WWIDによるby-id検索 |
| 3-3 | fc_util.go | `pkg/volume/fc/fc_util.go` | searchDisk()（199-249行目）: 2フェーズ検索のメインロジック |
| 3-4 | fc_util.go | `pkg/volume/fc/fc_util.go` | DetachDisk()（269-300行目）: デバイス切断処理 |

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

```
ProbeVolumePlugins() → fcPlugin
    │
    ├─ NewMounter() → fcDiskMounter
    │      └─ SetUpAt() → diskSetUp()
    │
    ├─ AttachDisk()
    │      └─ searchDisk()
    │             ├─ findDisk() [WWN+LUN]
    │             ├─ findDiskWWIDs() [WWID]
    │             └─ scsiHostRescan()
    │
    ├─ DetachDisk()
    │      ├─ EvalSymlinks()
    │      ├─ FindSlaveDevicesOnMultipath()
    │      ├─ deleteMultipathDevice()
    │      └─ detachFCDisk()
    │             ├─ flushDevice()
    │             └─ removeFromScsiSubsystem()
    │
    └─ NewUnmounter() → fcDiskUnmounter
           └─ TearDownAt() → CleanupMountPoint()
```

### データフロー図

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

PV Spec             ──▶ getWwnsLunWwids()       ──▶ wwns/lun/wwids
  (targetWWNs,
   lun, wwids)

wwns/lun/wwids      ──▶ searchDisk()            ──▶ devicePath
                         findDisk() or
                         findDiskWWIDs()

devicePath          ──▶ AttachDisk()             ──▶ verified devicePath
                         PathExists()

devicePath          ──▶ MountDevice/SetUpAt()    ──▶ mounted volume
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| fc.go | `pkg/volume/fc/fc.go` | ソース | プラグイン本体。データ構造、Mounter/Unmounter 生成 |
| fc_util.go | `pkg/volume/fc/fc_util.go` | ソース | FC ユーティリティ。デバイス検索、Attach/Detach 実装 |
| attacher.go | `pkg/volume/fc/attacher.go` | ソース | Attacher/Detacher 実装 |
| disk_manager.go | `pkg/volume/fc/disk_manager.go` | ソース | diskManager インターフェース |
| fc_test.go | `pkg/volume/fc/fc_test.go` | テスト | ユニットテスト |
