# 機能設計書 43-OS抽象化層（VFS）

## 概要

SQLiteがオペレーティングシステムと対話するための抽象化レイヤー（Virtual File System: VFS）の設計書。ファイルI/O、ロック、メモリマッピング等のOS依存操作を統一的なインターフェースで提供する。

### 本機能の処理概要

VFS（Virtual File System）は、SQLiteのOS依存部分を抽象化し、異なるプラットフォームや特殊な環境でも一貫したファイル操作を実現する基盤機能である。

**業務上の目的・背景**：SQLiteは組み込みシステムからデスクトップ、サーバーまで多様な環境で動作する必要がある。各OSのファイルシステム操作、ロック機構、時刻取得等は大きく異なるため、これらを抽象化することでコアロジックをプラットフォーム非依存に保つ。また、カスタムVFSを登録することで、暗号化、圧縮、インメモリ動作等の特殊な要件にも対応可能。

**機能の利用シーン**：
- データベースファイルのオープン・クローズ
- ページ読み書き（read/write）
- ファイルの同期（fsync）
- ファイルロック（共有・排他）
- WALモードでの共有メモリ操作
- 一時ファイルの作成・削除
- パス名の正規化
- 乱数生成、時刻取得

**主要な処理内容**：
1. VFS登録・検索（sqlite3_vfs_register/find）：カスタムVFSの登録とデフォルトVFSの取得
2. ファイルオープン（xOpen）：データベース、ジャーナル、WALファイルの作成・オープン
3. ファイルI/O（xRead/xWrite/xTruncate）：ページ単位のデータ読み書き
4. ファイルロック（xLock/xUnlock）：並行性制御のためのロック管理
5. ファイル同期（xSync）：ディスクへの確実な書き込み
6. 共有メモリ操作（xShmMap/xShmLock）：WALモードでのプロセス間通信
7. メモリマップI/O（xFetch/xUnfetch）：大規模ファイルの効率的アクセス
8. ユーティリティ（xRandomness/xSleep/xCurrentTime）：システムサービス

**関連システム・外部連携**：
- POSIXファイルシステムAPI（open, read, write, fcntl, mmap等）
- Windowsファイルシステム API（CreateFile, ReadFile, LockFile等）
- ミューテックスサブシステム（VFSリスト保護）

**権限による制御**：ファイルパーミッション（デフォルト0644）、ディレクトリパーミッション（0755）はOSレベルで制御

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | （内部機能） | - | すべてのデータベース操作の基盤として使用 |

## 機能種別

OS抽象化 / ファイルI/O / ロック管理 / システムサービス

## 入力仕様

### 入力パラメータ（sqlite3_vfsメソッド）

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| pVfs | sqlite3_vfs* | Yes | VFSオブジェクト | NULL不可 |
| zPath | const char* | Depends | ファイルパス | 最大512バイト |
| pFile | sqlite3_file* | Yes | ファイルハンドル格納先 | NULL不可 |
| flags | int | Yes | オープンフラグ | SQLITE_OPEN_*定数の組み合わせ |
| nBuf | int | Yes | バッファサイズ | 正の整数 |
| zBuf | char* | Yes | データバッファ | NULL不可 |

### オープンフラグ

| フラグ | 値 | 説明 |
|--------|-----|------|
| SQLITE_OPEN_READONLY | 0x00000001 | 読み取り専用 |
| SQLITE_OPEN_READWRITE | 0x00000002 | 読み書き可能 |
| SQLITE_OPEN_CREATE | 0x00000004 | 存在しなければ作成 |
| SQLITE_OPEN_EXCLUSIVE | 0x00000010 | 排他的作成 |
| SQLITE_OPEN_MAIN_DB | 0x00000100 | メインデータベース |
| SQLITE_OPEN_TEMP_DB | 0x00000200 | 一時データベース |
| SQLITE_OPEN_MAIN_JOURNAL | 0x00000800 | メインジャーナル |
| SQLITE_OPEN_WAL | 0x00080000 | WALファイル |

### ロックレベル

| レベル | 値 | 説明 |
|--------|-----|------|
| SQLITE_LOCK_NONE | 0 | ロックなし |
| SQLITE_LOCK_SHARED | 1 | 共有ロック（読み取り用） |
| SQLITE_LOCK_RESERVED | 2 | 予約ロック（書き込み予定） |
| SQLITE_LOCK_PENDING | 3 | 保留ロック（排他待ち） |
| SQLITE_LOCK_EXCLUSIVE | 4 | 排他ロック（書き込み中） |

### 入力データソース

- SQLiteコア（ページャ、WALモジュール）からの呼び出し
- アプリケーションからのカスタムVFS登録

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 操作結果 | int | SQLITE_OK（成功）または各種エラーコード |
| ファイルハンドル | sqlite3_file* | オープンされたファイル |
| 読み取りデータ | void* | xReadで取得したデータ |
| ファイルサイズ | i64 | xFileSizeで取得したサイズ |

### 出力先

- 呼び出し元への戻り値
- 指定バッファへのデータ書き込み

## 処理フロー

### 処理シーケンス

```
1. VFS初期化（sqlite3_os_init）
   ├─ プラットフォーム固有VFSを作成
   ├─ デフォルトVFSとして登録
   └─ システムコールテーブル初期化

2. ファイルオープン（unixOpen）
   ├─ パス検証とフラグ処理
   ├─ robust_open()でファイル記述子取得
   │   ├─ EINTRリトライ
   │   └─ 最小FD確保（<3は回避）
   ├─ unixFile構造体初期化
   ├─ ロック方式選択（POSIX/flock/dotfile等）
   └─ io_methodsテーブル設定

3. ファイル読み取り（unixRead）
   ├─ pread()/pread64()でオフセット指定読み取り
   ├─ 短い読み取り時は残りを0埋め
   └─ EINTRリトライ

4. ファイルロック（unixLock）
   ├─ 現在のロックレベル確認
   ├─ fcntl(F_SETLK)でPOSIXアドバイザリロック
   │   ├─ PENDING_BYTE取得（排他待ち）
   │   ├─ SHARED領域取得
   │   ├─ RESERVED_BYTE取得（書き込み予約）
   │   └─ EXCLUSIVE取得（全領域ロック）
   └─ ロック状態更新

5. ファイル同期（unixSync）
   ├─ 全データフラッシュ
   ├─ fdatasync()またはfsync()実行
   └─ ディレクトリ同期（必要時）
```

### フローチャート

```mermaid
flowchart TD
    A[sqlite3_vfs_find] --> B{zVfs指定?}
    B -->|Yes| C[名前でVFS検索]
    B -->|No| D[先頭VFS返却]
    C --> E[vfsList走査]
    E --> F{見つかった?}
    F -->|Yes| G[VFSポインタ返却]
    F -->|No| H[NULL返却]
    D --> G

    I[sqlite3OsOpen] --> J[pVfs->xOpen呼び出し]
    J --> K[unixOpen]
    K --> L[robust_open]
    L --> M{成功?}
    M -->|Yes| N[unixFile初期化]
    M -->|No| O[エラー返却]
    N --> P[io_methods設定]
    P --> Q[SQLITE_OK返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-43-01 | 最小FD制限 | FD 0,1,2（stdin/out/err）は使用しない | 常時 |
| BR-43-02 | ロック階層 | ロックは段階的に取得（NONE→SHARED→RESERVED→EXCLUSIVE） | ロック取得時 |
| BR-43-03 | EINTRリトライ | シグナル割り込み時は自動リトライ | open/read/write/fcntl |
| BR-43-04 | パーミッション継承 | WAL/ジャーナルはDBファイルと同じパーミッション | ファイル作成時 |
| BR-43-05 | VFS優先順位 | makeDflt=trueで登録されたVFSが先頭 | VFS登録時 |

### ロック方式

| 方式 | 対象環境 | 説明 |
|------|---------|------|
| POSIX Advisory Locks | Linux, macOS等 | デフォルト、fcntl(F_SETLK)使用 |
| flock | 一部Unix | BSD互換ロック |
| dot-file | NFS等 | ロックファイル（.lock）使用 |
| AFP | macOS | Apple Filing Protocol用 |
| none | 特殊用途 | ロックなし |

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

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

本機能はデータベーステーブルを直接操作しない（OS抽象化層のため）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| SQLITE_CANTOPEN | オープン失敗 | ファイルが存在しない/権限不足 | パス・権限確認 |
| SQLITE_BUSY | ロック競合 | 他プロセスがロック保持中 | リトライまたはビジータイムアウト |
| SQLITE_IOERR | I/Oエラー | ディスク障害等 | ハードウェア確認 |
| SQLITE_FULL | ディスクフル | 空き容量不足 | 空き容量確保 |
| SQLITE_READONLY | 読み取り専用 | 書き込み権限なし | 権限変更 |

### リトライ仕様

- EINTRエラー時は自動リトライ（robust_open, robust_ftruncate等）
- SQLITE_BUSY時はビジーハンドラで制御可能

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

VFSはトランザクションを直接管理しないが、ファイルロックと同期操作によりトランザクションの整合性を保証する。

## パフォーマンス要件

- pread/pwriteで位置指定I/O（lseek不要）
- メモリマップI/O（SQLITE_MAX_MMAP_SIZE>0時）で大規模ファイル効率化
- セクタサイズ検出でI/O最適化

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

- FD_CLOEXECで子プロセスへのFDリーク防止
- ファイルパーミッション設定（umask考慮）
- シンボリックリンク解決（readlink）

## 備考

- Unix系では複数のロック方式VFSが登録される（unix, unix-none, unix-dotfile等）
- SQLITE_DEFAULT_UNIX_VFSでデフォルトVFSを変更可能
- システムコールはaSyscall配列経由で呼び出し、テスト時にオーバーライド可能

---

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

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

### 推奨読解順序

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

VFSの抽象化インターフェースと具体的な構造体を理解。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | sqlite3.h | `src/sqlite3.h` | sqlite3_vfs構造体：VFSの抽象インターフェース |
| 1-2 | sqlite3.h | `src/sqlite3.h` | sqlite3_io_methods構造体：ファイル操作メソッド |
| 1-3 | os_unix.c | `src/os_unix.c` | struct unixFile（257-312行目）：Unix固有ファイル構造体 |

**読解のコツ**: sqlite3_vfsはVFSレベルの操作（open, delete, access等）、sqlite3_io_methodsは個別ファイルレベルの操作（read, write, lock等）を定義。

#### Step 2: VFS管理を理解する

VFSの登録・検索・管理の仕組みを把握。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | os.c | `src/os.c` | vfsList（355行目）：登録済みVFSのリンクリスト |
| 2-2 | os.c | `src/os.c` | sqlite3_vfs_find（362-381行目）：VFS検索 |
| 2-3 | os.c | `src/os.c` | sqlite3_vfs_register（408-431行目）：VFS登録 |

**主要処理フロー**:
1. **362行目**: sqlite3_vfs_find - 名前指定でVFS検索、NULLなら先頭返却
2. **419-427行目**: makeDflt=trueなら先頭に挿入、そうでなければ2番目
3. **374行目**: SQLITE_MUTEX_STATIC_MAINでスレッドセーフ保護

#### Step 3: OS抽象化ラッパーを理解する

sqlite3OsXXX関数群の実装を確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | os.c | `src/os.c` | sqlite3OsClose（82-87行目）：ファイルクローズ |
| 3-2 | os.c | `src/os.c` | sqlite3OsRead/Write（88-95行目）：読み書き |
| 3-3 | os.c | `src/os.c` | sqlite3OsOpen（215-232行目）：ファイルオープン |
| 3-4 | os.c | `src/os.c` | sqlite3OsLock/Unlock（107-115行目）：ロック操作 |

**主要処理フロー**:
- **84行目**: pId->pMethods->xClose(pId) - メソッドテーブル経由で呼び出し
- **229行目**: pVfs->xOpen - VFSのxOpenメソッド呼び出し

#### Step 4: Unix VFS実装を理解する

Unix環境でのVFS具体実装。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | os_unix.c | `src/os_unix.c` | aSyscall配列（423-596行目）：システムコールテーブル |
| 4-2 | os_unix.c | `src/os_unix.c` | robust_open（834-872行目）：堅牢なファイルオープン |
| 4-3 | os_unix.c | `src/os_unix.c` | unixSetSystemCall（731-767行目）：システムコール上書き |

**主要処理フロー**:
- **427-429行目**: osOpenマクロでaSyscall[0].pCurrentを呼び出し
- **837行目**: EINTRでwhileループ（割り込み時リトライ）
- **847行目**: FD<3なら/dev/null開いてFD確保

#### Step 5: ファイルロック実装を理解する

POSIXアドバイザリロックの実装詳細。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | os_unix.c | `src/os_unix.c` | unixEnterMutex/LeaveMutex（899-906行目）：グローバルミューテックス |
| 5-2 | os_unix.c | `src/os_unix.c` | ロックバイトオフセット（PENDING_BYTE, RESERVED_BYTE等） |

**主要処理フロー**:
- **898行目**: unixBigLockでinode情報を保護
- ロックは特定バイトオフセットへのfcntl(F_SETLK)で実装

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

```
sqlite3OsOpen(pVfs, zPath, pFile, flags, pFlagsOut)
    │
    └─ pVfs->xOpen()
           │
           ├─ [Unix] unixOpen()
           │      ├─ robust_open()
           │      │      └─ osOpen() ─── open()
           │      ├─ unixFile構造体初期化
           │      └─ ロック方式選択
           │             ├─ posixIoMethods
           │             ├─ nolockIoMethods
           │             └─ dotlockIoMethods
           │
           └─ [Windows] winOpen()

sqlite3OsRead(pFile, pBuf, amt, offset)
    │
    └─ pFile->pMethods->xRead()
           │
           ├─ [Unix] unixRead()
           │      └─ osPread() ─── pread()
           │
           └─ [Windows] winRead()

sqlite3_vfs_register(pVfs, makeDflt)
    │
    ├─ SQLITE_MUTEX_STATIC_MAIN取得
    ├─ vfsUnlink(pVfs) ─── 既存エントリ削除
    ├─ vfsList先頭/2番目に挿入
    └─ ミューテックス解放
```

### データフロー図

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

ファイルパス ──────▶ sqlite3OsOpen() ─────────────────▶ sqlite3_file*
                           │
                           ▼
                    ┌─────────────┐
                    │ sqlite3_vfs │
                    │   xOpen()   │
                    └─────────────┘
                           │
                           ▼
                    ┌─────────────┐
                    │ unixOpen    │
                    │ robust_open │
                    └─────────────┘
                           │
                           ▼
                    ┌─────────────┐
                    │ unixFile    │
                    │ ・h (fd)    │
                    │ ・pMethod   │
                    │ ・eFileLock │
                    └─────────────┘


読み書き要求 ─────▶ sqlite3OsRead/Write() ─────────▶ 読み取りデータ
                           │
                           ▼
                    ┌─────────────────┐
                    │ pMethods->xRead │
                    │ pMethods->xWrite│
                    └─────────────────┘
                           │
                           ▼
                    ┌─────────────────┐
                    │ pread/pwrite    │
                    │ (位置指定I/O)   │
                    └─────────────────┘
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| os.c | `src/os.c` | ソース | OS抽象化ラッパー、VFS管理 |
| os_unix.c | `src/os_unix.c` | ソース | Unix/Linux/macOS向けVFS実装 |
| os_win.c | `src/os_win.c` | ソース | Windows向けVFS実装 |
| os_common.h | `src/os_common.h` | ヘッダ | OS共通マクロ・定義 |
| sqlite3.h | `src/sqlite3.h` | ヘッダ | sqlite3_vfs、sqlite3_io_methods定義 |
| sqliteInt.h | `src/sqliteInt.h` | ヘッダ | 内部VFS関連定義 |
