# 通知設計書 15-Interop.Sys.INotify (IN_ACCESS)

## 概要

本ドキュメントは、Linux の inotify サブシステムが提供する `IN_ACCESS` 通知について、.NET ランタイムでの実装詳細と設計仕様を記述した通知設計書である。

### 本通知の処理概要

IN_ACCESS は、ファイルがアクセス（読み取り）された際に Linux カーネルの inotify サブシステムが生成する通知イベントである。.NET の FileSystemWatcher では、この通知を Changed イベントに変換してアプリケーションに通知する。

**業務上の目的・背景**：ファイルへの読み取りアクセスを監視することで、ファイルの利用状況追跡、セキュリティ監査、キャッシュ無効化判定、リソース使用状況の分析などの業務要件を実現できる。IN_ACCESS は NotifyFilters.LastAccess フィルタが設定されている場合に有効となり、ファイルの最終アクセス時刻の変更を検知するために使用される。

**通知の送信タイミング**：監視対象ディレクトリ内のファイルが read() システムコールでアクセスされた際に、カーネルが inotify イベントを生成する。このイベントは .NET の FileSystemWatcher.Linux 実装で処理され、Changed イベントとしてアプリケーションに通知される。

**通知の受信者**：FileSystemWatcher インスタンスの Changed イベントにハンドラを登録したアプリケーションコード。NotifyFilters に LastAccess が含まれている必要がある。

**通知内容の概要**：inotify イベントとして、ウォッチ記述子（wd）、イベントマスク（IN_ACCESS）、cookie（通常0）、ファイル名（name）が通知される。FileSystemWatcher は WatcherChangeTypes.Changed としてアプリケーションに伝達する。

**期待されるアクション**：受信者は通知を受け取り後、アクセスログの記録、セキュリティアラートの発報、キャッシュ管理、統計情報の更新などの処理を実行することが期待される。

## 通知種別

OSカーネル通知（inotify イベント）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（カーネルからの割り込み） |
| 優先度 | 通常（他の inotify イベントと同等） |
| リトライ | なし（カーネルは一度のみ通知） |

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

inotify_add_watch() で登録されたウォッチ記述子に対応する inotify ファイルディスクリプタに対してイベントが送信される。.NET では INotify クラスが全ての FileSystemWatcher で共有する単一の inotify インスタンスを管理する。

## 通知テンプレート

### inotify イベント構造

| 項目 | 内容 |
|-----|------|
| イベント型 | struct inotify_event |
| マスク値 | IN_ACCESS (0x00000001) |
| cookie | 0（ペアイベントではない） |

### イベントデータ構造

```c
struct inotify_event {
    int      wd;       // ウォッチ記述子
    uint32_t mask;     // IN_ACCESS = 0x00000001
    uint32_t cookie;   // 0
    uint32_t len;      // name の長さ
    char     name[];   // ファイル名（NULL終端）
};
```

### .NET での変換後

```csharp
// IN_ACCESS は Changed イベントに変換される
FileSystemEventArgs {
    ChangeType = WatcherChangeTypes.Changed,
    FullPath = "監視ディレクトリ/ファイル名",
    Name = "ファイル名"
}
```

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| wd | ウォッチ記述子 | inotify_add_watch() の戻り値 | Yes |
| mask | イベントマスク | IN_ACCESS (0x00000001) | Yes |
| cookie | イベント関連付け | 常に 0 | Yes |
| len | 名前長 | ファイル名のバイト長 + パディング | Yes |
| name | ファイル名 | 対象ファイルの名前 | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| システムコール | read() | ウォッチにIN_ACCESSが設定されている | ファイル読み取り時 |
| システムコール | execve() | ウォッチにIN_ACCESSが設定されている | 実行ファイルのロード時 |

### .NET での有効化条件

| 条件 | 説明 |
|-----|------|
| NotifyFilters.LastAccess | このフィルタが設定されている場合に IN_ACCESS が監視対象に含まれる |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| NotifyFilters に LastAccess が含まれない | .NET では IN_ACCESS をサブスクライブしない |
| ディレクトリへのアクセス | ディレクトリの読み取り（ls等）では通常発生しない |
| noatime マウントオプション | ファイルシステムが noatime でマウントされている場合、アクセス時刻が更新されない |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[ファイル read() 実行] --> B[カーネル: inotify イベント生成]
    B --> C[inotify キューに追加]
    C --> D[.NET: ProcessEvents スレッド]
    D --> E[TryReadEvent でイベント読み取り]
    E --> F{mask & IN_ACCESS?}
    F -->|Yes| G[WatcherEvent.Changed 生成]
    F -->|No| H[他のイベント処理]
    G --> I[_eventQueue に追加]
    I --> J[EmitEvent]
    J --> K[fsw.NotifyFileSystemEventArgs]
    K --> L[OnChanged 呼び出し]
    L --> M[終了]
```

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

### 参照テーブル一覧

該当なし（OSカーネル通知のためデータベースを使用しない）

### 更新テーブル一覧

該当なし

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| IN_Q_OVERFLOW | inotify イベントキューが溢れた | Error イベント発生、監視再起動 |
| EBADF | 無効なファイルディスクリプタ | 監視を停止 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし（カーネルイベントはリトライされない） |
| リトライ間隔 | 該当なし |
| リトライ対象エラー | 該当なし |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | カーネル設定依存（/proc/sys/fs/inotify/max_queued_events） |
| 1日あたり上限 | 制限なし |

### 配信時間帯

制限なし（24時間監視可能）

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

- IN_ACCESS はファイルアクセスパターンを明らかにするため、機密性の高い環境では監視ログの取り扱いに注意
- 監視対象ディレクトリへの読み取り権限が必要
- 他ユーザーのファイルアクセスは、適切な権限がない限り監視できない

## 備考

- IN_ACCESS は高頻度のファイルアクセスで大量のイベントを生成する可能性がある
- noatime マウントオプションを使用しているファイルシステムでは、IN_ACCESS が発生しない場合がある
- relatime マウントオプション（Linux デフォルト）では、アクセス時刻の更新が最適化されている
- .NET の FileSystemWatcher では NotifyFilters.LastAccess を設定した場合のみ IN_ACCESS が監視対象となる

---

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

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

### 推奨読解順序

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

まず、IN_ACCESS の定義と関連する定数を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Interop.INotify.cs | `src/libraries/Common/src/Interop/Linux/System.Native/Interop.INotify.cs` | IN_ACCESS 定数の定義（0x00000001） |

**読解のコツ**: NotifyEvents enum で IN_ACCESS = 0x00000001 として定義されている点に注目。

#### Step 2: フィルタマッピングを理解する

NotifyFilters から inotify イベントへの変換ロジックを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | FileSystemWatcher.Linux.cs | `src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.Linux.cs` | TranslateFilters メソッドでの IN_ACCESS マッピング |

**主要処理フロー**:
- **行 1261-1262 (Linux.cs)**: filtersForAccess に NotifyFilters.LastAccess が含まれる
- **行 1275-1278 (Linux.cs)**: IN_ACCESS をサブスクライブする条件判定

#### Step 3: イベント処理を理解する

IN_ACCESS イベントの処理フローを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | FileSystemWatcher.Linux.cs | `src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.Linux.cs` | ProcessEvent での IN_ACCESS 処理 |

**主要処理フロー**:
- **行 527-529 (Linux.cs)**: EventMask に IN_ACCESS が含まれる定義
- **行 685-688 (Linux.cs)**: IN_ACCESS イベントで WatcherEvent.Changed を生成

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

```
[Linux カーネル]
inotify イベント (IN_ACCESS)
    │
    ▼
[.NET FileSystemWatcher.Linux]
INotify.ProcessEvents()
    │
    ├─ TryReadEvent() → NotifyEvent 構造体
    │
    └─ ProcessEvent()
           │
           ├─ mask & IN_ACCESS 判定
           │
           └─ WatcherEvent.Changed(dir, name)
                  │
                  ▼
           Watcher.QueueEvent()
                  │
                  ▼
           EmitEvent()
                  │
                  ▼
           fsw.NotifyFileSystemEventArgs(Changed, name)
                  │
                  ▼
           OnChanged()
```

### データフロー図

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

ファイル read()         カーネル inotify
システムコール  ───▶    イベント生成  ───▶   inotify キュー
                              │
                              ▼
                        .NET read() ───▶   NotifyEvent 構造体
                              │
                              ▼
                        ProcessEvent()
                              │
                              ▼
                        WatcherEvent.Changed
                              │
                              ▼
                        FileSystemEventArgs ───▶  Changed イベント
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Interop.INotify.cs | `src/libraries/Common/src/Interop/Linux/System.Native/Interop.INotify.cs` | ソース | IN_ACCESS 定数定義 |
| FileSystemWatcher.Linux.cs | `src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.Linux.cs` | ソース | IN_ACCESS イベント処理 |
| FileSystemWatcher.cs | `src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.cs` | ソース | NotifyFilters、Changed イベント定義 |
