# 通知設計書 6-CDEV MEDIACHANGE

## 概要

本ドキュメントは、FreeBSDカーネルのDEVFS（デバイスファイルシステム）において、キャラクタデバイスのメディアが変更された際に発行されるdevctl通知「DEVFS CDEV MEDIACHANGE」の設計を記述する。

### 本通知の処理概要

GEOMのDEVクラスにおいてメディア変更が検知された際に、DEVFSサブシステム名でdevctlサブシステムを通じてユーザランドに通知を送信する処理である。GEOM DEV MEDIACHANGEと同時に発行される。

**業務上の目的・背景**：DEVFSレイヤにおけるキャラクタデバイスのメディア変更を、ユーザランドが検知するために本通知が必要となる。GEOM DEV MEDIACHANGEがGEOMサブシステムの観点からの通知であるのに対し、本通知はDEVFS（デバイスファイルシステム）の観点からの通知であり、devd(8)の設定ルールでシステム名による使い分けが可能である。

**通知の送信タイミング**：g_dev_set_media()関数内で、GEOM DEV MEDIACHANGE通知の直前に送信される。

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

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

**期待されるアクション**：受信したデーモンは、DEVFSレイヤでのデバイス状態更新、メディア再認識処理などを実行する。

## 通知種別

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

## 送信仕様

### 基本情報

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

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

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

## 通知テンプレート

### devctl通知メッセージ

| 項目 | 内容 |
|-----|------|
| system | `DEVFS` |
| subsystem | `CDEV` |
| type | `MEDIACHANGE` |
| data | `cdev=<デバイス名>` |

### 本文テンプレート

```
!system=DEVFS subsystem=CDEV type=MEDIACHANGE cdev=<デバイス名>
```

### 添付ファイル

該当なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| cdev | メディア変更が発生したデバイスのデバイス名 | dev->si_name（sc->sc_devまたはsc->sc_alias） | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| カーネル内部イベント | GEOM::media属性変更 | g_dev_attrchanged()がattr=="GEOM::media"で呼ばれた場合 | メインデバイスとエイリアスデバイスの両方に通知 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| sc->sc_alias == NULL | エイリアスデバイスが存在しない場合、エイリアス分の通知は発行されない |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[GEOM::media属性変更] --> B[g_dev_attrchanged呼出]
    B --> C[g_dev_set_media呼出]
    C --> D[sc->sc_devのsi_nameでbuf構築]
    D --> E[devctl_notify DEVFS CDEV MEDIACHANGE]
    E --> F[devctl_notify GEOM DEV MEDIACHANGE]
    F --> G{sc->sc_alias != NULL ?}
    G -->|Yes| H[sc->sc_aliasのsi_nameでbuf構築]
    H --> I[devctl_notify DEVFS CDEV MEDIACHANGE エイリアス]
    I --> J[devctl_notify GEOM DEV MEDIACHANGE エイリアス]
    J --> K[終了]
    G -->|No| K
```

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

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

| データ構造 | 用途 | 備考 |
|-----------|------|------|
| struct g_dev_softc | DEVクラスのソフト状態 | sc_devとsc_aliasを参照 |
| struct cdev | キャラクタデバイス | si_nameからデバイス名を取得 |

### 更新テーブル一覧

該当なし

## エラー処理

### エラーケース一覧

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

### リトライ仕様

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

## 配信設定

### レート制限

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

### 配信時間帯

制限なし

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

- /dev/devctlへのアクセスにはroot権限が必要

## 備考

- 本通知（DEVFS CDEV MEDIACHANGE）はGEOM DEV MEDIACHANGE（No.3）と常にペアで発行される
- 発行順序はDEVFS CDEV MEDIACHANGEが先、GEOM DEV MEDIACHANGEが後
- g_dev_set_media()内の行293がDEVFS通知、行294がGEOM通知
- エイリアスデバイスに対しても同様の順序で発行される（行298がDEVFS、行299がGEOM）

---

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

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

### 推奨読解順序

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

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | geom_dev.c | `sys/geom/geom_dev.c` | g_dev_set_media()関数（行283-301） |

**主要処理フロー**:
1. **行290-291**: sc = cp->private、dev = sc->sc_devでデバイスを取得
2. **行292**: snprintf(buf, sizeof(buf), "cdev=%s", dev->si_name)
3. **行293**: devctl_notify("DEVFS", "CDEV", "MEDIACHANGE", buf)
4. **行294**: devctl_notify("GEOM", "DEV", "MEDIACHANGE", buf)
5. **行295**: dev = sc->sc_aliasでエイリアスを取得
6. **行296-300**: エイリアスに対しても同様の通知を発行

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

```
g_dev_attrchanged(cp, "GEOM::media") [sys/geom/geom_dev.c:303]
    |
    +-- g_dev_set_media(cp) [sys/geom/geom_dev.c:283]
            |
            +-- devctl_notify("DEVFS", "CDEV", "MEDIACHANGE", buf) [行293] ← 本通知
            +-- devctl_notify("GEOM", "DEV", "MEDIACHANGE", buf) [行294]
            |
            +-- [エイリアスデバイスが存在する場合]
                    +-- devctl_notify("DEVFS", "CDEV", "MEDIACHANGE", buf) [行298] ← 本通知
                    +-- devctl_notify("GEOM", "DEV", "MEDIACHANGE", buf) [行299]
```

### データフロー図

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

GEOM::media属性変更      --->  g_dev_set_media()            --->  DEVFS CDEV MEDIACHANGE (本通知)
                                                                   GEOM DEV MEDIACHANGE (No.3)
                                                                      |
                                                              /dev/devctl
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| geom_dev.c | `sys/geom/geom_dev.c` | ソース | g_dev_set_media()でDEVFS CDEV MEDIACHANGE通知を発行 |
| devctl.h | `sys/sys/devctl.h` | ヘッダ | devctl_notify()のプロトタイプ |
| subr_bus.c | `sys/kern/subr_bus.c` | ソース | devctl_notify()の実装 |
