# 機能設計書 76-コアダンプ管理

## 概要

本ドキュメントは、FreeBSDのカーネルクラッシュダンプの保存・復号化機能の設計について記述する。dumpon(8)によるダンプデバイスの設定、savecore(8)によるクラッシュダンプの保存、decryptcore(8)による暗号化ダンプの復号化を中心に、カーネルパニック発生時の障害解析基盤を提供する。

### 本機能の処理概要

**業務上の目的・背景**：カーネルパニック発生時のメモリダンプは、障害の根本原因を特定するための最も重要な診断情報である。ダンプデバイスの事前設定、ダンプ後の安全な保存、暗号化ダンプの復号化により、カーネル開発者やシステム管理者がクラッシュの原因を解析できるようにする。

**機能の利用シーン**：システム初期設定時のダンプデバイス設定（dumpon）、システム再起動後のクラッシュダンプ保存（savecore）、セキュリティ要件のある環境での暗号化ダンプの復号（decryptcore）、ネットワーク経由でのリモートダンプ。

**主要な処理内容**：
1. dumpon(8): カーネルクラッシュダンプの出力先デバイス（ディスクパーティション/ネットワーク）を設定
2. savecore(8): ダンプデバイスからクラッシュダンプを読み出し、/var/crash等に保存。zlib/zstd圧縮対応
3. decryptcore(8): RSA暗号化されたカーネルダンプの復号化
4. ネットダンプ: ネットワーク経由でのリモートダンプ（dumpon -s server -c client）
5. 暗号化ダンプ: RSA公開鍵によるダンプ暗号化（dumpon -k pubkey）

**関連システム・外部連携**：カーネルダンプ機構（sys/kern/kern_dump.c）、OpenSSLによる暗号化/復号化、zlib/zstd圧縮ライブラリ、Capsicumサンドボックス、libxo出力。

**権限による制御**：dumpon、savecore、decryptcoreはすべてroot権限が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 25 | サービス選択画面 | 補助機能 | dumpdevのAUTO/NO設定 |

## 機能種別

システム管理 / 障害診断 / 暗号化処理

## 入力仕様

### 入力パラメータ（dumpon）

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| -i index | 整数 | No | ダンプインデックス（マルチダンプ用） | 0以上 |
| -r | フラグ | No | 指定インデックスのダンプ設定を削除 | なし |
| -v | フラグ | No | 詳細出力 | なし |
| -k pubkey | 文字列 | No | 暗号化用RSA公開鍵ファイル | PEM形式の有効な公開鍵 |
| -Z | フラグ | No | zstd圧縮有効化 | -zと排他 |
| -z | フラグ | No | zlib圧縮有効化 | -Zと排他 |
| -s server | 文字列 | No | ネットダンプサーバアドレス | -c必須 |
| -c client | 文字列 | No | ネットダンプクライアントアドレス | -s必須 |
| -g gateway | 文字列 | No | ネットダンプゲートウェイ | なし |
| device/iface | 文字列 | Yes | ダンプ先デバイスまたは"off" | デバイスパスまたはインタフェース名 |

### 入力パラメータ（savecore）

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| -C | フラグ | No | ダンプの存在チェックのみ（保存しない） | なし |
| -c | フラグ | No | ダンプをクリア | なし |
| -f | フラグ | No | ダンプ不正でも強制保存 | なし |
| -k | フラグ | No | 圧縮ダンプを展開せずに保存 | なし |
| -v | フラグ | No | 詳細出力 | なし |
| -z | フラグ | No | コア保存後に圧縮 | なし |
| directory | 文字列 | No | 保存先ディレクトリ（デフォルト: /var/crash） | 存在するディレクトリ |

### 入力データソース

- コマンドライン引数
- ダンプデバイス（カーネルが書き込んだクラッシュダンプ）
- RSA公開鍵/秘密鍵ファイル（暗号化/復号化用）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| vmcore.N | ファイル | カーネルクラッシュダンプファイル |
| vmcore.N.gz | ファイル | 圧縮されたクラッシュダンプ |
| info.N | ファイル | ダンプ情報ファイル |
| key.N | ファイル | 暗号化ダンプの復号鍵 |

### 出力先

- /var/crash/（デフォルトのダンプ保存ディレクトリ）
- 指定されたディレクトリ

## 処理フロー

### 処理シーケンス

```
dumpon:
1. 引数解析
   └─ デバイス/ネットワーク設定、暗号化/圧縮オプション
2. デバイスチェック
   └─ ダンプ先デバイスの存在・サイズ確認
3. カーネル設定
   └─ ioctl(DIOCSKERNELDUMP)でカーネルにダンプ設定を通知

savecore:
1. ダンプデバイスの特定
   └─ /etc/fstab、sysctlからダンプデバイスを決定
2. ダンプ有無チェック
   └─ ダンプヘッダの読み込みと検証
3. ダンプ保存
   └─ ダンプデバイスからファイルへコピー（圧縮/展開含む）
4. ディスク空き容量チェック
   └─ minfreeファイルの値と比較
5. ダンプクリア
   └─ ダンプデバイスのダンプヘッダをクリア

decryptcore:
1. 引数解析
   └─ 秘密鍵ファイル、暗号化コアファイルの指定
2. 鍵の読み込み
   └─ RSA秘密鍵の読み込み（PEM形式）
3. セッション鍵の復号
   └─ RSA秘密鍵でセッション鍵を復号
4. コアダンプの復号
   └─ AES（セッション鍵）でコアダンプを復号
```

### フローチャート

```mermaid
flowchart TD
    A[カーネルパニック発生] --> B[カーネルがダンプデバイスにメモリダンプ書き込み]
    B --> C[システム再起動]
    C --> D[savecore実行（RC起動時）]
    D --> E{ダンプ存在?}
    E -->|No| F[処理終了]
    E -->|Yes| G{暗号化?}
    G -->|Yes| H[暗号化ダンプを保存]
    G -->|No| I{圧縮?}
    I -->|Yes| J[圧縮ダンプを展開/保存]
    I -->|No| K[生ダンプを保存]
    H --> L[/var/crash/vmcore.N]
    J --> L
    K --> L
    L --> M[ダンプヘッダクリア]
    M --> N{暗号化ダンプ?}
    N -->|Yes| O[decryptcore実行]
    O --> P[復号済みコア]
    N -->|No| Q[kgdb等で解析]
    P --> Q
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-76-01 | ダンプデバイス事前設定 | カーネルパニック前にdumponでダンプデバイスを設定しておく必要がある | 常時 |
| BR-76-02 | minfreeチェック | 保存先の空き容量がminfreeファイルの値以下の場合はダンプを保存しない | savecore実行時 |
| BR-76-03 | ダンプ番号管理 | ダンプファイルは連番（vmcore.0, vmcore.1, ...）で管理される | savecore保存時 |
| BR-76-04 | 暗号化ダンプ | RSA公開鍵を指定するとダンプが暗号化され、秘密鍵なしには読めない | dumpon -k指定時 |
| BR-76-05 | ネットダンプ | NICインタフェースを指定してリモートサーバにダンプを送信可能 | dumpon -s/-c指定時 |

### 計算ロジック

- バッファサイズ: BUFFERSIZE = 1024*1024（1MB）（savecore.c 98行目）

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| - | - | - | データベースは使用しない |

### テーブル別操作詳細

該当なし。ダンプファイルはファイルシステム上に直接保存される。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| EX_USAGE | 使用法エラー | パラメータ不正 | usage表示 |
| - | デバイスアクセスエラー | ダンプデバイスオープン失敗 | エラーメッセージ出力 |
| - | 容量不足 | 保存先ディスク容量不足 | minfreeチェックで保存スキップ |
| - | ダンプ不正 | ダンプヘッダ不正、マジック不一致 | エラーメッセージ出力（-fで強制保存可） |
| - | 復号エラー | 秘密鍵不一致、暗号化データ破損 | OpenSSLエラーメッセージ出力 |

### リトライ仕様

リトライは行わない。ダンプ保存・復号化の失敗時はエラーメッセージを出力して終了する。

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

savecoreはダンプの保存とヘッダクリアを順序実行する。保存中の中断時にはダンプデバイス上のデータは保持されるため、再度savecoreを実行可能。

## パフォーマンス要件

- BUFFERSIZE（1MB）単位でのI/Oにより効率的なダンプコピーを実現
- zlib/zstd圧縮によりディスク使用量と保存時間を削減

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

- RSA暗号化によるダンプの機密性保護（カーネルメモリには秘密情報が含まれる可能性がある）
- Capsicumケイパビリティモードによるsavecoreのサンドボックス化
- decryptcoreは秘密鍵を使用するため、鍵ファイルのアクセス制御が重要
- /var/crashディレクトリのパーミッション管理

## 備考

- RC起動スクリプトにより、システム起動時にsavecoreが自動実行される
- bsdinstallのサービス選択画面でdumpdevの設定（AUTO/NO）が可能
- ネットダンプ機能はnetdumpプロトコル（sys/netinet/netdump/）を使用

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | kerneldump.h | `sys/sys/kerneldump.h` | kerneldumpheader構造体（ダンプヘッダ）、kerneldumpkey構造体（暗号化鍵）を理解する |

**読解のコツ**: カーネルダンプは、ヘッダ→データ→（暗号鍵）の構造でダンプデバイスに書き込まれる。ヘッダにはダンプサイズ、圧縮方式、暗号化方式等のメタデータが格納される。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | dumpon.c | `sbin/dumpon/dumpon.c` | usage関数（76-83行目）でコマンドオプションを確認、find_gateway関数（88-99行目）でネットダンプのゲートウェイ検索を理解する |

**主要処理フロー**:
1. **73-83行目**: usage関数（dumponの全オプション一覧）
2. **88-99行目**: find_gateway関数（ネットダンプ用のデフォルトゲートウェイ検索）

#### Step 3: savecoreの処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | savecore.c | `sbin/savecore/savecore.c` | BUFFERSIZE定義（98行目）、STATUS定数（100行目〜）、zlib/zstdによる圧縮・展開処理、Capsicumサンドボックスを理解する |

#### Step 4: decryptcoreの処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | decryptcore.c | `sbin/decryptcore/decryptcore.c` | DECRYPTCORE_CRASHDIR定義（49行目）、read_key関数（76-80行目）、OpenSSL APIの使用を理解する |

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

```
dumpon (sbin/dumpon/dumpon.c)
    |
    +-- main()
          +-- ioctl(DIOCSKERNELDUMP)  # カーネルダンプ設定
          +-- find_gateway()           # ネットダンプ用ゲートウェイ検索
          +-- RSA公開鍵読み込み        # 暗号化ダンプ用

savecore (sbin/savecore/savecore.c)
    |
    +-- main()
          +-- ダンプデバイス特定       # sysctl/fstab
          +-- ダンプヘッダ読み込み     # kerneldumpheader
          +-- ダンプデータコピー       # BUFFERSIZE単位I/O
          |     +-- zlib/zstd展開     # 圧縮ダンプの展開
          +-- ダンプヘッダクリア       # ダンプ済みマーク

decryptcore (sbin/decryptcore/decryptcore.c)
    |
    +-- main()
          +-- read_key()              # 暗号化鍵の読み込み
          +-- RSA復号                 # セッション鍵の復号
          +-- AES復号                 # コアダンプの復号
```

### データフロー図

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

カーネルパニック         カーネルダンプ機構           ダンプデバイス
(メモリ内容) -------->  kern_dump() --------->  (ディスクパーティション)

ダンプデバイス           savecore:                   /var/crash/vmcore.N
                  ----> ヘッダ読取 --> コピー ---> (ダンプファイル)
                         (zlib/zstd展開)             /var/crash/info.N

RSA秘密鍵              decryptcore:                 復号済みvmcore
                  ----> 鍵復号 --> AES復号  ---> (解析可能なコア)
暗号化vmcore
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| dumpon.c | `sbin/dumpon/dumpon.c` | ソース | ダンプデバイス設定コマンド |
| savecore.c | `sbin/savecore/savecore.c` | ソース | ダンプ保存コマンド |
| decryptcore.c | `sbin/decryptcore/decryptcore.c` | ソース | ダンプ復号化コマンド |
| kerneldump.h | `sys/sys/kerneldump.h` | ヘッダ | ダンプヘッダ・鍵構造体定義 |
| netdump.h | `sys/netinet/netdump/netdump.h` | ヘッダ | ネットダンププロトコル定義 |
| dumpon.8 | `sbin/dumpon/dumpon.8` | マニュアル | dumponコマンドのmanページ |
| savecore.8 | `sbin/savecore/savecore.8` | マニュアル | savecoreコマンドのmanページ |
| decryptcore.8 | `sbin/decryptcore/decryptcore.8` | マニュアル | decryptcoreコマンドのmanページ |
| minfree | `sbin/savecore/minfree` | 設定 | ダンプ保存先最小空き容量設定スクリプト |
