# 通知設計書 4-DEV SIZECHANGE

## 概要

本ドキュメントは、FreeBSDカーネルのGEOMフレームワークにおいて、ディスクサイズが変更された際に発行されるdevctl通知「GEOM DEV SIZECHANGE」の設計を記述する。

### 本通知の処理概要

GEOMプロバイダのサイズ（mediasize）が変更された際に、DEVクラスのresizeコールバック経由でdevctlサブシステムを通じてユーザランドに通知を送信する処理である。

**業務上の目的・背景**：仮想ディスクのオンラインリサイズや、ストレージデバイスのサイズ変更を検知するために本通知が必要となる。これにより、ファイルシステムのオンライン拡張やパーティションテーブルの更新を自動化できる。

**通知の送信タイミング**：GEOMプロバイダのresize処理（g_resize_provider()）が実行された際に、DEVクラスのresizeコールバック（g_dev_resize()）が呼ばれ、通知が送信される。

**通知の受信者**：devd(8)デーモンおよび/dev/devctlをモニタリングしているユーザランドプロセスが受信する。

**通知内容の概要**：サイズ変更が発生したプロバイダのデバイス名が「cdev=デバイス名」形式で通知される。

**期待されるアクション**：受信したデーモンは、パーティションテーブルの再読み込み、ファイルシステムの拡張、監視システムへの通知などを実行する。

## 通知種別

カーネル内devctl通知（/dev/devctl経由のユーザランド通知）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 非同期（devctlキューへのエンキュー） |
| 優先度 | 通常 |
| リトライ | なし |

### 送信先決定ロジック

devctl_notify()により全リスナーにブロードキャストされる。

## 通知テンプレート

### devctl通知メッセージ

| 項目 | 内容 |
|-----|------|
| system | `GEOM` |
| subsystem | `DEV` |
| type | `SIZECHANGE` |
| data | `cdev=<デバイス名>` |

### 本文テンプレート

```
!system=GEOM subsystem=DEV type=SIZECHANGE cdev=<デバイス名>
```

### 添付ファイル

該当なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| cdev | サイズ変更が発生したプロバイダのデバイス名 | cp->provider->name | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| カーネル内部イベント | g_dev_resize()呼出 | GEOMプロバイダのresizeイベント | g_resize_provider()経由で呼ばれる |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| なし | g_dev_resize()が呼ばれた場合は常に通知が発行される |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[ディスクサイズ変更] --> B[disk_resize / g_resize_provider]
    B --> C[g_dev_resize コールバック]
    C --> D[KNOTE_UNLOCKED NOTE_ATTRIB]
    D --> E[snprintf buf cdev=provider名]
    E --> F[devctl_notify GEOM DEV SIZECHANGE buf]
    F --> G[終了]
```

## データベース参照・更新仕様

### カーネル内データ構造

| データ構造 | 用途 | 備考 |
|-----------|------|------|
| struct g_consumer | GEOMコンシューマ | cp->providerからプロバイダ名を取得 |
| struct g_dev_softc | DEVクラスのソフト状態 | sc_selinfoのknoteリストに通知 |

### 更新テーブル一覧

該当なし

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| なし | g_dev_resize()はvoid関数 | N/A |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし |
| リトライ間隔 | N/A |
| リトライ対象エラー | N/A |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | 制限なし |
| 1日あたり上限 | 制限なし |

### 配信時間帯

制限なし

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

- /dev/devctlへのアクセスにはroot権限が必要
- 通知に含まれるのはプロバイダ名のみ

## 備考

- g_dev_resize()はKNOTE_UNLOCKEDでNOTE_ATTRIBイベントも発行するため、kqueue(2)でデバイスノードをモニタリングしているプロセスにもサイズ変更が通知される
- デバイス名はcp->provider->nameから取得され、sc->sc_dev->si_nameではない点に注意

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | geom_dev.c | `sys/geom/geom_dev.c` | g_dev_softc構造体（行60-70）：sc_selinfoフィールド |

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | geom_dev.c | `sys/geom/geom_dev.c` | g_dev_resize()関数（行318-329）：resizeコールバック |

**主要処理フロー**:
1. **行324**: sc = cp->privateでソフト状態を取得
2. **行325**: KNOTE_UNLOCKED()でNOTE_ATTRIBイベントを発行
3. **行327**: snprintf(buf, sizeof(buf), "cdev=%s", cp->provider->name)
4. **行328**: devctl_notify("GEOM", "DEV", "SIZECHANGE", buf)

#### Step 3: 上位の呼び出し元を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | geom_disk.c | `sys/geom/geom_disk.c` | disk_resize()関数（行1053-1061）およびg_disk_resize()関数（行670-694） |

**主要処理フロー**:
- **行1060**: g_post_event(g_disk_resize, dp, ...)でイベント投入
- **行692**: g_resize_provider(pp, dp->d_mediasize)でプロバイダサイズを更新

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

```
disk_resize() [sys/geom/geom_disk.c:1053]
    |
    +-- g_post_event(g_disk_resize, ...) [行1060]
            |
            +-- g_disk_resize() [sys/geom/geom_disk.c:670]
                    |
                    +-- g_resize_provider() [GEOMフレームワーク]
                            |
                            +-- g_dev_resize() [sys/geom/geom_dev.c:318]
                                    |
                                    +-- KNOTE_UNLOCKED(NOTE_ATTRIB)
                                    +-- devctl_notify("GEOM","DEV","SIZECHANGE",...)
```

### データフロー図

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

ディスクサイズ変更        --->  disk_resize()                --->  g_resize_provider()
(dp->d_mediasize更新)           |                                   |
                                v                                   v
                          g_disk_resize()                    g_dev_resize()
                                                                    |
                                                                    +-- KNOTE (kqueue通知)
                                                                    +-- devctl_notify()
                                                                          |
                                                                          v
                                                                  /dev/devctl
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| geom_dev.c | `sys/geom/geom_dev.c` | ソース | g_dev_resize()でSIZECHANGE通知を発行 |
| geom_disk.c | `sys/geom/geom_disk.c` | ソース | disk_resize()が上位のエントリーポイント |
| devctl.h | `sys/sys/devctl.h` | ヘッダ | devctl_notify()のプロトタイプ |
| subr_bus.c | `sys/kern/subr_bus.c` | ソース | devctl_notify()の実装 |
