# 機能設計書 7-sysctl管理

## 概要

本ドキュメントは、FreeBSDにおけるsysctl管理機能の設計を記述する。カーネルパラメータの動的な参照・変更を行うsysctlフレームワークを対象とする。

### 本機能の処理概要

**業務上の目的・背景**：sysctlフレームワークはカーネルパラメータの動的な参照・変更を可能にし、システムの再起動やカーネル再コンパイルなしにカーネルの動作を調整できる。システムチューニング、セキュリティ設定、デバッグ情報取得、ハードウェア情報参照など広範な用途に使用される。

**機能の利用シーン**：システムのパフォーマンスチューニング（vm.swappiness等）、セキュリティ設定変更（security.bsd.see_other_uids等）、ネットワークパラメータ調整（net.inet.tcp.*）、ハードウェア情報の取得（hw.physmem等）、デバッグ情報の参照（debug.*）で利用される。

**主要な処理内容**：
1. **sysctl(8)コマンド**: ユーザ空間からのカーネルパラメータ操作CLI。MIB（Management Information Base）名を指定してパラメータの参照・変更を行う。
2. **kern_sysctl.cフレームワーク**: カーネル内のsysctlツリー管理。SYSCTL_NODE/SYSCTL_INT/SYSCTL_STRING等のマクロによるパラメータ登録、sysctl()システムコールによるアクセス。
3. **MIBツリー管理**: 階層的な名前空間（kern.*, vm.*, net.*, hw.*, debug.*, security.*等）によるパラメータの組織化。
4. **sysctl.conf**: 起動時に自動適用されるsysctlパラメータ設定ファイル。

**関連システム・外部連携**：カーネル全サブシステム（各サブシステムがsysctlパラメータを登録）、rc.conf/sysctl.conf（起動時設定）、bsdinstallインストーラ（セキュリティ設定画面）、jail（jail固有のsysctl制限）。

**権限による制御**：読み取り専用パラメータは一般ユーザでもアクセス可能。書き込み可能パラメータ（CTLFLAG_RW）はroot権限が必要。CTLFLAG_SECUREフラグ付きパラメータはsecurelevel制限に従う。jailからのアクセスはCTLFLAG_PRISON等で制御される。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 26 | セキュリティ強化設定画面 | 補助機能 | sysctl.confへのセキュリティ関連カーネルパラメータ書き込み |

## 機能種別

カーネル基盤機能（パラメータ管理・システムチューニング）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| MIB名 | char * | Yes | パラメータ名（例: kern.maxproc） | 有効なMIBパス |
| 設定値 | char * | No | 設定する値（変更時） | パラメータ型に合致 |
| -a フラグ | - | No | 全パラメータ表示 | - |
| -n フラグ | - | No | 名前なし（値のみ表示） | - |
| -w フラグ | - | No | 書き込みモード | root権限必要 |

### 入力データソース

sysctl(8)コマンドのCLI引数、sysctl()システムコール、/etc/sysctl.conf設定ファイル。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| パラメータ値 | 可変 | int, string, struct等のパラメータ値 |
| 旧値 | 可変 | 変更前の値（oldp引数） |

### 出力先

標準出力（sysctl(8)コマンド）、ユーザ空間バッファ（sysctl()システムコール）。

## 処理フロー

### 処理シーケンス

```
1. パラメータ参照
   ├─ sysctl(8)コマンド / sysctl()syscall
   │    ├─ MIB名からOIDへの変換（name2oid）
   │    ├─ sysctlツリーの走査
   │    ├─ ハンドラ関数の呼び出し
   │    └─ 値のcopyout（カーネル→ユーザ空間）

2. パラメータ変更
   ├─ sysctl(8)コマンド / sysctl()syscall
   │    ├─ 権限チェック（priv_check / securelevel）
   │    ├─ MIB名からOIDへの変換
   │    ├─ 新値のcopyin（ユーザ空間→カーネル）
   │    ├─ ハンドラ関数の呼び出し（バリデーション含む）
   │    └─ カーネルパラメータの更新

3. 起動時設定
   └─ /etc/rc.d/sysctl → sysctl -f /etc/sysctl.conf
```

### フローチャート

```mermaid
flowchart TD
    A[sysctl コマンド] --> B{操作種別}
    B -->|参照| C[name2oid: MIB→OID変換]
    B -->|変更| D[権限チェック]
    D --> E{root権限?}
    E -->|No| F[EPERM]
    E -->|Yes| C
    C --> G[sysctlツリー走査]
    G --> H[ハンドラ関数呼出]
    H --> I{参照 or 変更?}
    I -->|参照| J[copyout: 値返却]
    I -->|変更| K[copyin: 新値取得]
    K --> L[パラメータ更新]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 読み取り権限 | CTLFLAG_RDパラメータは一般ユーザアクセス可 | 参照操作時 |
| BR-02 | 書き込み権限 | CTLFLAG_RWパラメータはroot権限必要 | 変更操作時 |
| BR-03 | securelevel制限 | CTLFLAG_SECUREパラメータはsecurelevel制限 | securelevel > 0時 |
| BR-04 | jail制限 | CTLFLAG_PRISONパラメータはjail内から変更可能 | jail環境時 |
| BR-05 | チューンテーブル | CTLFLAG_RDTUNパラメータは起動時のみ設定可能 | loader.conf経由 |
| BR-06 | MPSAFE | CTLFLAG_MPSAFE付きハンドラはGiant Lock不要 | マルチプロセッサ環境 |

### 計算ロジック

sysctlツリーはOID（Object Identifier）の階層構造で管理され、各ノードにハンドラ関数が登録される。値の取得・設定はstruct sysctl_reqを介して行われ、oldp（旧値出力）とnewp（新値入力）を同時に処理できる。

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

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

| 操作 | 対象データ構造 | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 参照 | sysctlツリー | SELECT | OIDに対応するパラメータ値の取得 |
| 変更 | sysctlツリー | UPDATE | OIDに対応するパラメータ値の変更 |
| 登録 | sysctlツリー | INSERT | SYSCTLマクロによるパラメータ登録 |

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

#### struct sysctl_oid

| 操作 | 項目（フィールド名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| 参照 | oid_handler | ハンドラ関数呼び出し | sysctl_handle_int等 |
| 参照 | oid_arg1 | パラメータへのポインタ | カーネル変数のアドレス |
| 登録 | oid_kind | CTLFLAG_RD/RW/MPSAFE等 | アクセス制御フラグ |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ENOENT | 不存在 | 指定MIB名が存在しない | 正しいMIB名を指定（sysctl -aで一覧確認） |
| EPERM | 権限不足 | 非rootでのRWパラメータ変更 | root権限で実行 |
| EINVAL | 引数不正 | 不正な値の設定 | パラメータの型・範囲を確認 |
| ENOMEM | バッファ不足 | oldlenp指定のバッファが小さい | 十分なバッファサイズを指定 |

### リトライ仕様

sysctl操作は即座に成功または失敗する。リトライは不要。

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

各sysctlハンドラは必要に応じて適切なロックを取得する。CTLFLAG_MPSAFE付きハンドラはGiant Lock不要。ハンドラ内でのロック取得はハンドラ実装者の責任。

## パフォーマンス要件

- sysctl参照: マイクロ秒オーダー（ツリー走査 + ハンドラ実行）
- sysctl変更: マイクロ秒オーダー（ロック取得含む）

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

- CTLFLAG_SECUREによるsecurelevel制限で、本番環境でのセキュリティパラメータ変更を防止
- jail環境でのsysctlアクセス制限（security.jail.sysvipc_allowed等）
- セキュリティ強化設定画面（画面No.26）でのsysctl.conf設定

## 備考

- kern_sysctl.cは3135行の大きなファイルであり、sysctlフレームワークの中核を実装
- sysctl(8)コマンド（sbin/sysctl/sysctl.c）はEFI変数やBIOS情報の表示にも対応している
- SYSCTL_NODE/SYSCTL_INT等のマクロによりカーネルソースコード内でパラメータを宣言的に登録できる

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | sysctl.h | `sys/sys/sysctl.h` | struct sysctl_oid、SYSCTL_*マクロ群の定義 |
| 1-2 | sysctl.h | `sys/sys/sysctl.h` | CTLFLAGフラグ定義（CTLFLAG_RD, RW, MPSAFE, PRISON等） |

**読解のコツ**: SYSCTL_INT(_kern, OID_AUTO, maxproc, ...)のようなマクロ呼び出しが各サブシステムに散在している。これらはリンカセットにより起動時に自動的にsysctlツリーに登録される。

#### Step 2: ユーザ空間コマンドを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | sysctl.c | `sbin/sysctl/sysctl.c` | main()関数とMIB名のパース処理 |

**主要処理フロー**:
1. sysctl(8)はsysctl()システムコールを呼び出してカーネルパラメータにアクセスする
2. -aフラグで全パラメータを列挙、個別MIB名で特定パラメータにアクセス

#### Step 3: カーネルフレームワークを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | kern_sysctl.c | `sys/kern/kern_sysctl.c` | sysctlフレームワーク主要実装（3135行）。sysctl_find_oid()、sysctl_root()等 |

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

```
sysctl(8) コマンド
    |
    +-- sysctl() システムコール
            |
            +-- kern___sysctl()
                    +-- sysctl_find_oid() [OID検索]
                    +-- sysctl_root() [ルートハンドラ]
                            +-- oid->oid_handler() [パラメータ固有ハンドラ]
                                    +-- sysctl_handle_int()
                                    +-- sysctl_handle_string()
                                    +-- sysctl_handle_opaque()
                                    +-- (カスタムハンドラ)
```

### データフロー図

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

MIB名文字列 ────> name2oid変換 ────────────────────> OID配列

OID + oldp ─────> sysctl_root() ───────────────────> パラメータ値(oldp)
OID + newp ─────> oid_handler() ───────────────────> パラメータ更新

sysctl.conf ────> sysctl -f で一括適用 ────────────> カーネルパラメータ設定
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| sysctl.c | `sbin/sysctl/sysctl.c` | ソース | sysctl(8)コマンド実装 |
| kern_sysctl.c | `sys/kern/kern_sysctl.c` | ソース | sysctlカーネルフレームワーク（3135行） |
| sysctl.h | `sys/sys/sysctl.h` | ヘッダ | sysctl構造体・マクロ定義 |
| sysctl.conf | `sbin/sysctl/sysctl.conf` | 設定ファイル | sysctl起動時設定テンプレート |
| sysctl.8 | `sbin/sysctl/sysctl.8` | manページ | sysctlコマンドマニュアル |
