# 帳票設計書 12-repquota - ファイルシステムクォータ要約レポート

## 概要

本ドキュメントは、FreeBSD の `repquota` コマンドが出力するファイルシステムクォータ要約レポートの設計仕様を記述する。

### 本帳票の処理概要

repquota は、UFSファイルシステムのクォータ情報を要約してレポートするユーティリティである。ユーザーまたはグループごとのディスク使用量とクォータ制限値を一覧表形式で出力する。

**業務上の目的・背景**：ファイルシステムの容量管理において、各ユーザー・グループのディスク使用状況とクォータ設定の遵守状況を一覧で把握するために使用される。ディスク容量の逼迫予防、クォータ超過ユーザーの特定、容量計画立案のためのデータ収集などの課題を解決する。

**帳票の利用シーン**：定期的なディスク容量監視、クォータ超過ユーザーへの通知準備、ファイルシステム容量計画策定、ストレージ管理レビューなどの場面で利用される。

**主要な出力内容**：
1. ユーザー/グループ名
2. クォータ超過状態（ブロック/ファイル数のソフトリミット超過フラグ）
3. 現在のブロック使用量、ソフトリミット、ハードリミット
4. ブロッククォータの猶予期間
5. 現在のファイル（inode）使用数、ソフトリミット、ハードリミット
6. ファイルクォータの猶予期間

**帳票の出力タイミング**：管理者がコマンドラインから `repquota` コマンドを実行した際にリアルタイムで標準出力に出力される。

**帳票の利用者**：システム管理者、ストレージ管理者

## 帳票種別

集計表（ユーザー/グループ別ディスククォータ要約）

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| N/A | コマンドラインインターフェース | N/A | `repquota` コマンド実行 |

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | テキスト（標準出力） |
| 用紙サイズ | N/A |
| 向き | N/A |
| ファイル名 | N/A（標準出力） |
| 出力方法 | 標準出力（stdout） |
| 文字コード | ロケール依存 |

## 帳票レイアウト

### レイアウト概要

ヘッダー行付きのテーブル形式で、各ユーザー/グループの行が続く。ファイルシステムごとにセクションが分かれる。

```
┌──────────────────────────────────────────────────────────────┐
│ *** Report for {type} quotas on {mount} ({device}) ***      │
├──────────────────────────────────────────────────────────────┤
│ ヘッダー行（Block limits / File limits）                     │
│ カラムヘッダー行                                             │
├──────────────────────────────────────────────────────────────┤
│ ユーザー/グループ別データ行（繰り返し）                       │
└──────────────────────────────────────────────────────────────┘
```

### ヘッダー部

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | レポートタイトル | クォータ種別・マウントポイント・デバイス名 | fstab構造体 | "*** Report for %s quotas on %s (%s)" |
| 2 | カラムヘッダー1 | ブロック制限・ファイル制限の大見出し | 固定文字列 | "Block limits / File limits" |
| 3 | カラムヘッダー2 | 各カラムの見出し | 固定文字列 | "used soft hard grace / used soft hard grace" |

### 明細部

| No | 項目名 | 説明 | データ取得元 | 表示形式 | 列幅 |
|----|-------|------|-------------|---------|-----|
| 1 | ユーザー/グループ名 | ID対応の名前 | fileusage.fu_name | 左寄せ、max(MAXLOGNAME-1,10)幅 | 10-15文字 |
| 2 | ブロック超過フラグ | ソフトリミット超過時'+',未超過時'-' | dqbuf.dqb_curblocks >= dqb_bsoftlimit | 1文字 | 1文字 |
| 3 | ファイル超過フラグ | ソフトリミット超過時'+',未超過時'-' | dqbuf.dqb_curinodes >= dqb_isoftlimit | 1文字 | 1文字 |
| 4 | ブロック使用量 | 現在のブロック使用量 | dqbuf.dqb_curblocks | KBまたはhuman-readable | 6-7文字 |
| 5 | ブロックソフトリミット | ブロック数のソフト制限 | dqbuf.dqb_bsoftlimit | KBまたはhuman-readable | 6-7文字 |
| 6 | ブロックハードリミット | ブロック数のハード制限 | dqbuf.dqb_bhardlimit | KBまたはhuman-readable | 6-7文字 |
| 7 | ブロック猶予期間 | ソフトリミット超過時の残り猶予 | dqbuf.dqb_btime | 日数/時:分/分 | 6文字 |
| 8 | ファイル使用数 | 現在のinode使用数 | dqbuf.dqb_curinodes | 整数 | 7文字 |
| 9 | ファイルソフトリミット | inode数のソフト制限 | dqbuf.dqb_isoftlimit | 整数 | 7文字 |
| 10 | ファイルハードリミット | inode数のハード制限 | dqbuf.dqb_ihardlimit | 整数 | 7文字 |
| 11 | ファイル猶予期間 | ソフトリミット超過時の残り猶予 | dqbuf.dqb_itime | 日数/時:分/分 | 6文字 |

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| ファイルシステム指定 | 対象UFSファイルシステムを指定（-a で全て） | Yes |
| クォータ種別 | ユーザークォータ(-u)、グループクォータ(-g) | No（デフォルト: -u） |
| 使用量ゼロ除外 | curinodes==0 かつ curblocks==0 のエントリは除外 | 自動 |

### ソート順

| 優先度 | 項目 | 昇順/降順 |
|-------|------|---------|
| 1 | ユーザー/グループID | 昇順（0からmaxidまで順次走査） |

### 改ページ条件

ファイルシステムごとにセクション分け（空行挿入）

## データベース参照仕様

### 参照テーブル一覧

| テーブル名 | 用途 | 結合条件 |
|-----------|------|---------|
| クォータファイル | クォータ情報読み取り | quota_open/quota_read |
| /etc/fstab | UFSファイルシステム列挙 | fs_vfstype == "ufs" |
| パスワードデータベース | UID→ユーザー名変換 | pw_uid |
| グループデータベース | GID→グループ名変換 | gr_gid |

### テーブル別参照項目詳細

#### クォータファイル（struct dqblk）

| 参照項目（カラム名） | 帳票項目との対応 | 取得条件 | 備考 |
|-------------------|----------------|---------|------|
| dqb_curblocks | ブロック使用量 | quota_read() | dbtokb()で変換 |
| dqb_bsoftlimit | ブロックソフトリミット | quota_read() | dbtokb()で変換 |
| dqb_bhardlimit | ブロックハードリミット | quota_read() | dbtokb()で変換 |
| dqb_btime | ブロック猶予期間 | quota_read() | timeprt()で表示形式変換 |
| dqb_curinodes | ファイル使用数 | quota_read() | 整数表示 |
| dqb_isoftlimit | ファイルソフトリミット | quota_read() | 整数表示 |
| dqb_ihardlimit | ファイルハードリミット | quota_read() | 整数表示 |
| dqb_itime | ファイル猶予期間 | quota_read() | timeprt()で表示形式変換 |

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| ブロック使用量(KB) | dbtokb(dqb_curblocks) | DEV_BSHIFTに依存 | マクロdbtokbで変換 |
| 猶予期間表示 | (dqb_btime - now) を日/時:分/分に変換 | 30秒単位丸め | timeprt()関数 |
| 超過フラグ | bsoftlimit > 0 && curblocks >= bsoftlimit ? '+' : '-' | N/A | ブロック・ファイル各々 |
| human-readable表示 | humanize_number() | 自動 | -h オプション時 |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[repquotaコマンド実行] --> B[オプション解析]
    B --> C{-a指定?}
    C -->|Yes| D[全UFSファイルシステム走査]
    C -->|No| E[指定ファイルシステム走査]
    D --> F[ユーザー/グループ名テーブル構築]
    E --> F
    F --> G[quota_open でクォータファイルオープン]
    G --> H[ID 0 から maxid までループ]
    H --> I[quota_read でクォータ読み取り]
    I --> J{使用量 > 0?}
    J -->|No| H
    J -->|Yes| K[フォーマット出力]
    K --> H
    H --> L[quota_close]
    L --> M[終了]
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| クォータファイルなし | quota_open失敗 | "No %s quotas on %s (%s)"（-v時） | 次のファイルシステムに進む |
| fstab未登録 | 指定FSがfstabにない | "%s not found in fstab" | warnx()で警告表示 |
| メモリ不足 | calloc失敗 | "out of memory for fileusage structures" | errx(1,...) で終了 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | ユーザー数 * ファイルシステム数（数十〜数千エントリ） |
| 目標出力時間 | クォータファイルI/O速度に依存 |
| 同時出力数上限 | 制限なし |

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

- クォータ情報の参照にはroot権限が必要
- パスワード・グループデータベースの参照（-n未指定時）
- 全ユーザーのディスク使用量情報が出力されるため、アクセス制御が重要

## 備考

- UFSファイルシステムのみサポート（fs_vfstype == "ufs" フィルタ、行151）
- -h オプションで human-readable 表示（humanize_number使用）
- -n オプションでID数値表示（名前解決を省略）
- -v オプションでクォータなしのファイルシステムも報告

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | quota.h | `ufs/ufs/quota.h` | struct dqblk の定義、MAXQUOTAS/USRQUOTA/GRPQUOTA定数、INITQFNAMES |
| 1-2 | repquota.c | `usr.sbin/repquota/repquota.c` | struct fileusage の定義（行72-77）、FUHASHとハッシュテーブル（行78-79） |

**読解のコツ**: dqblkはUFSクォータの基本構造体。ブロック数はDEV_BSIZE単位で格納されているため、dbtokb()マクロ（行59-66）で変換が必要。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | repquota.c | `usr.sbin/repquota/repquota.c` | main()（行96-174）：オプション解析、ユーザー/グループテーブル構築、ファイルシステム走査 |

**主要処理フロー**:
1. **行104-127**: getoptによるオプション解析（-a, -g, -h, -n, -u, -v）
2. **行137-148**: ユーザー/グループ名のハッシュテーブル構築（setpwent/setgrent使用）
3. **行149-169**: fstab走査とrepquota()呼び出し

#### Step 3: レポート出力処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | repquota.c | `usr.sbin/repquota/repquota.c` | repquota()（行186-248）：クォータファイルオープン、ID走査、フォーマット出力 |

**主要処理フロー**:
- **行194**: quota_open() でクォータファイルオープン
- **行213**: quota_maxid() で最大IDを取得
- **行214-245**: ID 0 から maxid までループし quota_read() で各エントリを読み取り・出力
- **行246**: quota_close() でクリーンアップ

#### Step 4: ユーティリティ関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | repquota.c | `usr.sbin/repquota/repquota.c` | prthumanval()（行250-266）：human-readable表示、timeprt()（行332-359）：猶予期間フォーマット、lookup()/addid()：ハッシュテーブル管理 |

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

```
main() [repquota.c:96]
    |
    +-- getopt() [オプション解析]
    |
    +-- setpwent()/getpwent()/addid() [ユーザー名テーブル構築]
    +-- setgrent()/getgrent()/addid() [グループ名テーブル構築]
    |
    +-- setfsent()/getfsent() [fstab走査]
    |
    +-- repquota() [repquota.c:186]
            |
            +-- quota_open() [クォータファイルオープン]
            +-- quota_maxid() [最大ID取得]
            +-- quota_read() [クォータ読み取り]
            +-- lookup()/addid() [名前解決]
            +-- prthumanval() [使用量表示]
            +-- timeprt() [猶予期間表示]
            +-- quota_close() [クリーンアップ]
```

### データフロー図

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

/etc/fstab ──────────> main(): FS走査 ──────────────> stdout
クォータファイル ─────> repquota(): クォータ読取り        (テキストテーブル)
/etc/passwd ─────────> addid(): UID→名前変換
/etc/group ──────────> addid(): GID→名前変換
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| repquota.c | `usr.sbin/repquota/repquota.c` | ソース | メインプログラム全体 |
| quota.h | `ufs/ufs/quota.h` | ヘッダ | dqblk構造体、クォータ定数定義 |
| Makefile | `usr.sbin/repquota/Makefile` | ビルド | ビルド設定（libutil依存） |
