# 画面設計書 17-手動パーティション編集画面

## 概要

本ドキュメントは、FreeBSD bsdinstallインストーラにおける手動パーティション編集画面の設計書である。GEOMフレームワークを使用してディスクパーティションを手動で作成・編集するTUI画面について記述する。C言語で実装されたbsddialogベースのパーティションエディタである。

### 本画面の処理概要

この画面では、システムに接続されたディスクのパーティションテーブルを視覚的に表示し、パーティションの作成・削除・編集・リバートを対話的に行う。

**業務上の目的・背景**：Auto ZFS/Auto UFSでは対応できない特殊なパーティション構成が必要な場合や、既存パーティションを保持しながら新規パーティションを追加したい場合に使用する。上級ユーザ向けの画面であり、GEOM（FreeBSDのストレージフレームワーク）の知識が前提となる。

**画面へのアクセス方法**：パーティションモード選択画面（No.15）で「Manual」を選択した場合に遷移する。`bsdinstall partedit` コマンドで呼び出される。また、`autopart`（ガイド付きUFSパーティション）でも内部的に使用される。

**主要な操作・処理内容**：
1. GEOMメッシュからディスクとパーティションの階層構造を読み取り、一覧表示する
2. Create：選択したプロバイダにパーティションを作成する
3. Delete：選択したパーティションを削除する
4. Modify：選択したパーティションのマウントポイントやファイルシステムを編集する
5. Revert：全ての変更を取り消す
6. Auto：UFSガイド付きパーティション設定を実行する
7. Finish：変更をコミットし、fstabを生成する

**画面遷移**：
- 遷移元：パーティションモード選択画面（No.15）のManual選択
- 遷移先（Finish・Commit）：マウント処理後、インストール実行フローへ
- 遷移先（Revert & Exit）：パーティションモード選択画面に戻る

**権限による表示制御**：sade（Stand-Alone Disk Editor）モードで起動した場合、インストーラ固有のバリデーション（ルートパーティション必須チェック等）が緩和される。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 26 | GEOMストレージフレームワーク | 主機能 | GEOMベースのディスクパーティション手動作成・編集処理 |
| 11 | UFS/FFS | 補助機能 | UFSパーティションの作成・マウントポイント設定 |
| 12 | ZFS | 補助機能 | ZFSパーティションの作成オプション |

## 画面種別

対話型TUI（C言語実装、bsddialogベース）

## URL/ルーティング

TUIベースのbsddialogインターフェース。URLは存在しない。
- 呼び出し：`bsdinstall partedit`
- 実体バイナリ：`usr.sbin/bsdinstall/partedit/partedit.c` からコンパイル

## 入出力項目

| 項目名 | 入出力 | 型 | 必須 | 初期値 | 説明 |
|--------|--------|------|------|--------|------|
| パーティション操作 | 入力（ボタン） | ボタン選択 | はい | - | Create/Delete/Modify/Revert/Auto/Finish |
| パーティション選択 | 入力（選択） | リスト選択 | はい | - | 操作対象のディスク/パーティションを選択 |

## 表示項目

| 項目名 | 表示位置 | 説明 |
|--------|----------|------|
| バックタイトル | 画面上部 | "$OSNAME Installer"（非sadeモード時） |
| タイトル | ダイアログタイトル | "Partition Editor" |
| プロンプト | リスト上部 | "Create partitions for FreeBSD, F1 for help." |
| ディスク/パーティション一覧 | メインリスト | 名前、サイズ、タイプ、マウントポイントをインデント付きで階層表示 |
| ボタン | 画面下部 | Create / Delete / Modify / Revert / Auto / Finish |

## イベント仕様

### 1-Create（BUTTON_CREATE = BSDDIALOG_OK）

選択されたプロバイダ（ディスクまたは空き領域）に対して `gpart_create` を呼び出し、パーティション作成ダイアログを表示する（行150-151）。

### 2-Delete（BUTTON_DELETE = BSDDIALOG_EXTRA）

選択されたパーティションを `gpart_delete` で削除する（行153-154）。

### 3-Modify（BUTTON_MODIFY = BSDDIALOG_CANCEL）

選択されたパーティションの `gpart_edit` を呼び出し、マウントポイントやファイルシステムタイプを編集する（行156-157）。

### 4-Revert（BUTTON_REVERT = BSDDIALOG_HELP）

`gpart_revert_all` で全ての変更を取り消し、パーティションメタデータをクリアして初期状態に戻す（行159-178）。

### 5-Auto（BUTTON_AUTO = BSDDIALOG_RIGHT1）

`part_wizard("ufs")` を呼び出し、UFSガイド付きパーティション設定を実行する（行180-181）。

### 6-Finish（BUTTON_FINISH = BSDDIALOG_RIGHT2）

1. 確認ダイアログ「Your changes will now be written to disk.」を表示する（行186-194）
2. Commit選択時：`validate_setup`でルートパーティションの存在を確認し、`apply_changes`で変更をコミットする
3. Revert & Exit選択時：全変更を取り消して終了する
4. Back選択時：エディタに戻る

## データベース更新仕様

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| Finish-Commit | ディスクパーティション | WRITE | gpart commitで物理ディスクにパーティション書き込み |
| Finish-Commit | $PATH_FSTAB | WRITE | fstabファイルの生成 |
| Create/Delete/Modify | GEOMメッシュ | UPDATE | メモリ上のパーティション構成変更（未コミット） |

### テーブル別更新項目詳細

#### fstab（$PATH_FSTAB）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| WRITE | fs_spec | パーティションデバイスパス | /dev/ada0p2等 |
| WRITE | fs_file | マウントポイント | /, /home等 |
| WRITE | fs_vfstype | ファイルシステムタイプ | ufs, swap等 |
| WRITE | fs_mntops | マウントオプション | rw等 |
| WRITE | fs_freq | ダンプ頻度 | 数値 |
| WRITE | fs_passno | fsckパス番号 | 数値 |

## メッセージ仕様

| 種別 | 条件 | メッセージ |
|------|------|-----------|
| エラー | ディスク未検出 | "No disks found. If you need to install a kernel driver, choose Shell at the installation menu." |
| エラー | ルートパーティション未設定 | "No root partition was found. The root FreeBSD partition must have a mountpoint of '/'." |
| 警告 | ルートパーティションが未フォーマット | "The chosen root partition has a preexisting filesystem..." |
| 確認 | Finish時 | "Your changes will now be written to disk. If you have chosen to overwrite existing data, it will be PERMANENTLY ERASED." |
| 情報 | Finish処理中 | "Initializing file systems. Please wait." |

## 例外処理

| 条件 | 動作 |
|------|------|
| ディスク未検出 | エラーメッセージ表示後にループを抜ける |
| ルートパーティション未設定 | バリデーションエラーでFinish処理を中断 |
| fstabファイルオープン失敗 | エラーメッセージ表示、-1返却 |
| SIGINT受信 | gpart_revert_allで全変更取消後、bsddialog_endで終了 |

## 備考

- C言語で実装されており、libgeom(3)を使用してGEOMメッシュ情報を取得する
- bsddialog(3)ライブラリを直接使用したTUI実装である
- sade（Stand-Alone Disk Editor）としても動作可能で、progname="sade"で判定される
- autopartとしても動作可能で、progname="autopart"でガイド付きモードになる
- scriptedpartとしても動作可能で、コマンドライン引数でスクリプト実行する
- SIGINTハンドラにより、Ctrl-C押下時に全変更がリバートされてから終了する
- マウントポイント順でfstabエントリをソートする（mountpoint_sorter関数）

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | partedit.h | `usr.sbin/bsdinstall/partedit/partedit.h` | partition_metadata構造体（名前、fstab、newfsコマンド）とpmetadata_headキューを理解する |
| 1-2 | diskmenu.h | `usr.sbin/bsdinstall/partedit/diskmenu.h` | partedit_item構造体（インデント、名前、サイズ、タイプ、マウントポイント）とボタン定義を理解する |

**読解のコツ**: libgeomのgmesh/gclass/ggeom/gprovider階層がディスク→パーティションの階層構造を表現する。TAILQ_HEADマクロで定義されたリンクリストでパーティションメタデータを管理する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | partedit.c | `usr.sbin/bsdinstall/partedit/partedit.c` | 行74-232のmain関数。プログラム名による動作モード判定、GEOMメッシュ読み取り、メインループ、ボタンイベント処理を理解する |

**主要処理フロー**:
1. **行86-87**: プログラム名による動作モード判定（sade/autopart/scriptedpart/partedit）
2. **行89-97**: TAILQ初期化、fstabメタデータ読み込み、bsddialog初期化
3. **行103-122**: 動作モードに応じたプロンプト設定とpart_wizard呼び出し
4. **行125-213**: メインイベントループ（GEOMメッシュ読み取り→diskmenu_show→ボタン処理）
5. **行185-209**: Finish処理（確認ダイアログ→validate_setup→apply_changes）

#### Step 3: 変更適用処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | partedit.c | `usr.sbin/bsdinstall/partedit/partedit.c` | 行339-457のapply_changes関数。gpart_commitによるパーティション書き込み、newfsによるファイルシステム初期化、fstab生成を理解する |

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

```
bsdinstall partedit (usr.sbin/bsdinstall/partedit/partedit.c)
    |
    +-- main()
           |
           +-- init_fstab_metadata() - 既存fstab読み込み
           +-- bsddialog_init() - TUI初期化
           |
           +-- [メインループ]
                  +-- geom_gettree() - GEOMメッシュ取得
                  +-- read_geom_mesh() - ディスク/パーティション列挙
                  +-- get_mount_points() - マウントポイント情報付加
                  +-- diskmenu_show() - TUIメニュー表示
                  |
                  +-- [Create] --> gpart_create()
                  +-- [Delete] --> gpart_delete()
                  +-- [Modify] --> gpart_edit()
                  +-- [Revert] --> gpart_revert_all()
                  +-- [Auto]   --> part_wizard("ufs")
                  +-- [Finish] --> validate_setup() --> apply_changes()
                                                           +-- gpart_commit()
                                                           +-- system(newfs)
                                                           +-- fstab書き込み
```

### データフロー図

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

GEOMカーネル ---------> geom_gettree() ---------> gmesh構造体
                              |
                              v
                        read_geom_mesh() --------> partedit_item配列
                              |                       (ディスク/パーティション一覧)
                              v
ユーザ操作 ----------> diskmenu_show() ---------> ボタンイベント
  Create/Delete/                                      |
  Modify/Revert/                                      v
  Auto/Finish                                   gpart_*操作
                                                      |
                                                      v
                                                apply_changes()
                                                      |
                                                      +-> gpart_commit() --> ディスク
                                                      +-> system(newfs) --> FS初期化
                                                      +-> fopen(fstab) --> fstab
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| partedit.c | `usr.sbin/bsdinstall/partedit/partedit.c` | ソース | パーティションエディタのメインプログラム（629行） |
| partedit.h | `usr.sbin/bsdinstall/partedit/partedit.h` | ヘッダ | データ構造定義とgpart操作関数宣言 |
| diskmenu.h | `usr.sbin/bsdinstall/partedit/diskmenu.h` | ヘッダ | メニュー項目構造体とボタン定数定義 |
| gpart_ops.c | `usr.sbin/bsdinstall/partedit/gpart_ops.c` | ソース | gpart操作の実装（推定） |
| diskmenu.c | `usr.sbin/bsdinstall/partedit/diskmenu.c` | ソース | ディスクメニュー表示の実装（推定） |
| part_wizard.c | `usr.sbin/bsdinstall/partedit/part_wizard.c` | ソース | ガイド付きパーティション設定の実装（推定） |
