# バッチ設計書 10-222.backup-gmirror

## 概要

本ドキュメントは、FreeBSD periodicフレームワークにおける日次gmirrorバックアップバッチ `222.backup-gmirror` の設計を記述する。本バッチは `gmirror list` の出力をバックアップし、gmirrorの構成情報を保持する。

### 本バッチの処理概要

本バッチは、`gmirror(8)` で構成されたソフトウェアRAIDミラーの構成情報を `gmirror list` コマンドで取得し、バックアップとして保存する処理を行う。

**業務上の目的・背景**：gmirror(8) はFreeBSDのGEOMフレームワークに基づくソフトウェアRAID1（ミラーリング）機能である。ミラーの構成情報（使用するディスク、同期状態、パラメータ等）は障害復旧時に必要となる。本バッチにより、gmirrorの構成情報を日次で自動バックアップし、ミラー構成の変更検知と障害復旧への備えを提供する。また、同期中（COMPLETE以外の状態）のミラーはバックアップをスキップすることで、不安定な状態の記録を回避する。

**バッチの実行タイミング**：日次（daily）。FreeBSD periodicフレームワークにより実行される。

**主要な処理内容**：
1. `/etc/defaults/periodic.conf` および上書き設定ファイルの読み込み
2. `daily_backup_gmirror_enable` 変数による有効/無効判定
3. `gmirror status` でアクティブなgmirrorデバイスを列挙
4. 各gmirrorデバイスについて、同期状態が全てCOMPLETEであることを確認
5. `gmirror list` の出力を .tmp ファイルに保存
6. `rotate` 関数で前回バックアップとの差分管理

**前後の処理との関連**：daily periodicのバックアップカテゴリ（200番台）に属する。`221.backup-gpart` に続いて実行される。

**影響範囲**：`/var/backups` ディレクトリ内のバックアップファイル。gmirrorデバイスからの読み取りのみ。

## バッチ種別

データ連携（ストレージ構成バックアップ）

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | 日次 |
| 実行時刻 | periodic(8)のcron設定に依存 |
| 実行曜日 | 毎日 |
| 実行日 | 毎日 |
| トリガー | cron経由でperiodic(8)から起動 |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| periodic.confの存在 | `/etc/defaults/periodic.conf` が読み取り可能であること |
| daily_backup_gmirror_enable=YES | 明示的に有効化が必要（デフォルトはNO） |
| gmirror(8)の存在 | gmirror コマンドが利用可能であること |
| gmirrorデバイスの存在 | gmirror status でデバイスが検出されること |

### 実行可否判定

`daily_backup_gmirror_enable` が `YES` の場合に実行する。デフォルトは `NO`。`gmirror status` でgmirrorデバイスが検出されない場合はrc=2。同期中のミラーはバックアップ対象からスキップされる。

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| daily_backup_gmirror_enable | 文字列 | Yes | NO | バッチの有効/無効フラグ |
| daily_backup_gmirror_verbose | 文字列 | No | NO | 差分がある場合の詳細出力 |
| daily_diff_flags | 文字列 | No | -b -U 0 | diff コマンドのフラグ |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| /etc/defaults/periodic.conf | シェル変数定義 | デフォルト設定値 |
| gmirror status | コマンド出力 | アクティブなgmirrorデバイス一覧 |
| gmirror list | コマンド出力 | gmirrorデバイスの詳細情報 |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| /var/backups/gmirror.{ミラー名}.bak | テキスト | gmirror listの出力バックアップ |
| /var/backups/gmirror.{ミラー名}.bak2 | テキスト | 前回のバックアップ |
| 標準出力 | テキスト | 処理メッセージおよび差分情報 |
| 終了コード | 数値 | 0:変更なし、1:変更あり、2:gmirrorなし、3:実行エラー |

### 出力ファイル仕様

| 項目 | 内容 |
|-----|------|
| ファイル名 | gmirror.{ミラー名}.bak / gmirror.{ミラー名}.bak2 |
| 出力先 | /var/backups/ |
| 文字コード | システムデフォルト |
| 区切り文字 | N/A |

## 処理フロー

### 処理シーケンス

```
1. 設定ファイル読み込み
   └─ periodic.conf を source
2. 有効/無効判定
   └─ daily_backup_gmirror_enable が YES かどうか判定
3. gmirrorデバイス列挙
   └─ gmirror status 2>/dev/null | awk で mirror/ プレフィックスを除いたデバイス名を抽出
4. デバイスの存在確認
   └─ デバイスが検出されない場合は rc=2
5. 各ミラーに対して処理
   └─ gmirror status -s でCOMPLETE以外のコンポーネントがないか確認
   └─ 全てCOMPLETEなら gmirror list の出力を .tmp に保存
   └─ rotate 関数で .bak と比較・ローテーション
```

### フローチャート

```mermaid
flowchart TD
    A[バッチ開始] --> B[periodic.conf読み込み]
    B --> C{daily_backup_gmirror_enable=YES?}
    C -->|No| Z[rc=0で終了]
    C -->|Yes| D[gmirror statusでデバイス列挙]
    D --> E{gmirrorデバイスあり?}
    E -->|No| F[rc=2, メッセージ出力]
    E -->|Yes| G[各ミラーをループ]
    G --> H{全コンポーネントCOMPLETE?}
    H -->|No| I[バックアップスキップ]
    H -->|Yes| J[gmirror listを.tmpに保存]
    J --> K[rotate関数でバックアップ管理]
    K --> G
    I --> G
    G --> Z2[終了]
    F --> Z2
```

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

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

本バッチはデータベースを使用しない。

| 処理 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| N/A | N/A | N/A | データベース操作なし |

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

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| rc=2 | 環境不備 | gmirrorデバイスが検出されない | gmirrorを使用していない環境では正常 |
| rc=3 | 実行エラー | mv コマンドの失敗 | /var/backups のパーミッションを確認する |
| rc=1 | 情報通知 | 前回との差分が検出された | ミラー構成の変更を確認する |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし |
| リトライ間隔 | N/A |
| リトライ対象エラー | N/A |

### 障害時対応

リトライ機構はない。次回のdaily実行時に再度実行される。同期中のミラーはスキップされるため、同期完了後にバックアップが取得される。

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

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | なし（ファイルシステム操作） |
| コミットタイミング | 各バックアップは即時書き込み |
| ロールバック条件 | ロールバック機構なし。.bak2 に前回バックアップ保持 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | gmirrorデバイス数に依存（通常少数） |
| 目標処理時間 | 数秒以内 |
| メモリ使用量上限 | gmirror/cmp/diff コマンドの使用量（低い） |

## 排他制御

排他制御の仕組みは実装されていない。`gmirror status -s` で同期中のミラーを検出した場合はバックアップをスキップする（不安定状態のバックアップを回避）。

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| 開始ログ | 処理開始時 | "Backup of gmirror information for:" |
| 進捗ログ | 各ミラー処理時 | ミラー名の出力 |
| 差分ログ | verbose有効・差分検出時 | diff出力 |
| エラーログ | gmirror未検出時 | "no gmirrors found" メッセージ |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| 終了コード | rc=1 | periodic(8)の出力先（変更検出通知） |
| 終了コード | rc >= 2 | periodic(8)の出力先（エラー通知） |

## 備考

- デフォルトでは無効（daily_backup_gmirror_enable=NO）
- 同期中（COMPLETE以外の状態）のミラーはバックアップをスキップする
- `daily_backup_gmirror_verbose` はデフォルトNO
- `rotate` 関数は `221.backup-gpart` と同じパターンで実装されている（ただし独自に定義）
- ミラー名に含まれる特殊文字は `tr -cs ".[:alnum:]\n" "_"` でアンダースコアに変換される
- gmirror status の stderr は /dev/null にリダイレクトされるため、gmirrorが利用不可の環境でもエラーは抑制される
- Created by: Miroslav Lachman
