ディスクストレージ管理：パーティションの方法とコツ


# ディスクストレージ管理 - ディスクパーティション

## ディスクスペースの使用プロセス
1. デバイスのパーティション分割
2. ファイルシステムの作成
3. 新しいファイルシステムのマウント

## 1.1 ディスクパーティション

### 1.1.1 なぜパーティションを分割するのか
- I/Oパフォーマンスの最適化
- ディスクスペースのクォータ制限を実現
- 修復速度の向上
- システムとプログラムの分離
- 複数のOSをインストール
- 異なるファイルシステムの採用

### 1.1.2 パーティションの方式
2つのパーティション方式：MBR、GPT

#### 1.1.2.1 MBRパーティション
MBR：Master Boot Record、1982年、32ビットでセクタ数を表し、パーティションは2Tを超えない。

**パーティション分割の単位：**
- CentOS 5以前はシリンダ単位で分割
- CentOS 6以降はセクタ単位で分割可能

**0トラック0セクタ：512バイト**
- 446バイト: ブートローダー起動関連
- 64バイト：パーティションテーブル、各16バイトで1つのパーティションを識別
- 2バイト: 55AA、識別マーク

MBRパーティションでは1つのハードディスクに最大4つのプライマリパーティションを持つことができ、3つのプライマリパーティション+1つの拡張パーティション（N個の論理パーティション）も可能。プライマリと拡張パーティションは1--4に対応し、/dev/sda3、論理パーティションは5から始まる、/dev/sda5。

**MBRパーティションの構造**

**なぜプライマリパーティションは4つを超えられないのか？**
0トラック0セクタにパーティションテーブル情報を格納するための64バイトのスペースしかないため、1つのパーティションのキー情報は16バイトを必要とする。

**なぜ1つのパーティションは2Tを超えられないのか？**
1つのパーティション情報は16バイトを使用し、開始位置と終了位置をそれぞれ4バイトで記録する。1バイトは8ビットで、4バイトは32ビット。したがって、最大で2の32乗個のセクタがあり、1セクタは512バイトなので、最大スペースは2^32 * 2^9 = 2^41バイト。2^40はTなので、2^41は2Tを超えない。

ハードディスクのMBRは4つの部分で構成される：
- 主ブートプログラム（オフセットアドレス0000H--0088H）、これはアクティブパーティションからシステムブートプログラムをロードして実行する
- エラーメッセージデータ領域、オフセットアドレス0089H--00E1Hはエラーメッセージ、00E2H--01BDHはすべて0バイト
- パーティションテーブル（DPT, Disk Partition Table）には4つのパーティションエントリが含まれ、オフセットアドレス01BEH--01FDH、各パーティションエントリは16バイト、合計64バイトはパーティションエントリ1、パーティションエントリ2、パーティションエントリ3、パーティションエントリ4
- 終了マーク、オフセットアドレス01FE--01FFの2バイト値は終了マーク55AA

#### 例1：パーティションテーブル情報の確認
```shell
[root@rocky86 ~]# hexdump -C -n 512 /dev/sda
```

#### 例2： MBRのパーティションテーブルをバックアップし、破壊後に復元
```shell
#パーティションテーブルの確認
[root@rocky86 ~]# fdisk -l /dev/sda
Disk /dev/sda: 200 GiB, 214748364800 bytes, 419430400 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x5b8e1003
Device     Boot   Start       End   Sectors Size Id Type
/dev/sda1 *       2048   2099199   2097152   1G 83 Linux
/dev/sda2       2099200 419430399 417331200 199G 8e Linux LVM

#MBRパーティションテーブルをバックアップ
[root@rocky86 ~]# dd if=/dev/sda of=/data/dpt.img bs=1 count=64 skip=446

#64バイトのサイズ
[root@rocky86 ~]# ll /data/dpt.img 
-rw-r--r-- 1 root root 64 Jul 30 11:49 /tmp/dpt.img

#具体的な内容を確認
[root@rocky86 ~]# hexdump -vC /data/dpt.img

#リモートにバックアップ
[root@rocky86 ~]# scp /tmp/dpt.img 10.0.0.157:

#MBRパーティションテーブルを破壊
[root@rocky86 ~]# dd if=/dev/zero of=/dev/sda bs=1 count=64 seek=446
64+0 records in
64+0 records out
64 bytes copied, 0.00248682 s, 25.7 kB/s

#再度512バイトを確認
[root@rocky86 ~]# hexdump -vC -n 512 /dev/sda

#再度パーティションテーブルを確認、パーティション情報なし
[root@rocky86 ~]# fdisk -l /dev/sda
Disk /dev/sda: 200 GiB, 214748364800 bytes, 419430400 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x3475e2b0

#メモリには関連情報が残っている
[root@rocky86 ~]# lsblk
NAME       MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda           8:0    0 200G  0 disk 
├─sda1        8:1    0   1G  0 part /boot
└─sda2        8:2    0 199G  0 part 
 ├─rl-root 253:0    0   70G  0 lvm /
 ├─rl-swap 253:1    0   2G  0 lvm [SWAP]
 └─rl-home 253:2    0 127G  0 lvm /home
sr0          11:0    1 10.5G  0 rom 

#再起動後、システムに入れない
[root@rocky86 ~]# reboot

#CDで起動し、Rescueモードに入り、3番目のオプションを選択し、シェルに進む
#ネットワークを設定
ifconfig ens160 10.0.0.158/24

#リモートからパーティションテーブル情報を取得
scp 10.0.0.157:/root/dpt.img .

#MBRパーティションテーブルを復元
dd if=dpt.img of=/dev/sda bs=1 seek=446

#再起動
reboot
```
### 1.1.2.2 GPTパーティション
GPT：GUID（Globals Unique Identifiers）パーティションテーブルは128個のパーティションをサポートし、64ビットを使用し、8Z（512バイト/ブロック）、64Z（4096バイト/ブロック）をサポートします。
128ビットのUUID（Universally Unique Identifier）を使用してディスクとパーティションを表します。GPTパーティションテーブルは自動的にヘッドとテールにバックアップされ、CRCチェックサムがあります。
UEFI（Unified Extensible Firmware Interface 統一拡張ファームウェアインターフェイス）ハードウェアはGPTをサポートし、これによりオペレーティングシステムが起動できます。

GPTパーティション構造は4つの領域に分かれています：

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3515709/de348538-a2d7-cb5d-05c9-833f958152f4.png)


- GPTヘッド
- パーティションテーブル
- GPTパーティション
- バックアップ領域

#### 例3：ubuntuのデフォルトでGPTパーティションを使用
```shell
root@ubuntu22:~# fdisk -l /dev/sda
Disk /dev/sda: 200 GiB, 214748364800 bytes, 419430400 sectors
Disk model: VMware Virtual S
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: D7BA0964-556C-4442-87F5-9B57ACD27E8A
Device       Start       End   Sectors Size Type
/dev/sda1     2048      4095      2048   1M BIOS boot
/dev/sda2     4096   4198399   4194304   2G Linux filesystem
/dev/sda3  4198400 419428351 415229952 198G Linux filesystem
```

### 1.1.3 BIOSとUEFI
- BIOSはコンピュータのマザーボードに組み込まれたプログラムで、主に起動時のシステム自己診断とオペレーティングシステムのブートに使用されます。現在の新しいコンピュータは基本的にUEFIブートを採用しています。
- BIOS（Basic Input Output System 基本入力出力システム）は主にシステムハードウェアの自己診断とオペレーティングシステムのブートを完了します。オペレーティングシステムのブートが始まると、BIOSの役割は終了します。システムハードウェアの自己診断：システムハードウェアに故障がある場合、マザーボード上のスピーカーは異なる長さの「ビープ音」を発し、ハードウェアの故障を簡単に判断できます。例えば、「1長1短」は通常メモリの故障を示し、「1長3短」は通常グラフィックカードの故障を示します。
- BIOSは1975年に誕生し、アセンブリ言語で書かれ、当初は16ビットしかなく、1Mのメモリにしかアクセスできませんでした。そのうちの前640Kは基本メモリと呼ばれ、後384Kはブートや各種BIOS自身の使用のために予約されていました。BIOSはMBR（マスターブートレコード）で初期化されたハードディスクしか認識できず、最大2Tのハードディスクと4つのプライマリパーティション（拡張パーティション内の論理パーティションを除く）をサポートします。しかし、現在は64ビットシステムが一般的に実現されており、伝統的なBIOSは要求を満たすことができません。この時、インテルが主導するEFIが誕生しました。
- EFI（Extensible Firmware Interface 拡張ファームウェアインターフェイス）は、IntelがPCファームウェアのアーキテクチャ、インターフェイス、およびサービスの提案標準として提案したものです。その主な目的は、OSのロード前（ブート前）にすべてのプラットフォーム上で一貫性のある正しく指定されたブートサービスを提供することです。BIOSの後継者として見なされるか、新しいバージョンのBIOSとして理解されます。
- UEFIはEFI1.10を基盤として発展し、その所有者はもはやIntelではなく、Unified EFI Forumという国際組織です。
- UEFI（Unified Extensible Firmware Interface 統一拡張ファームウェアインターフェイス）は、タイプインターフェイスの詳細な記述標準です。UEFIは軽量なオペレーティングシステムに相当し、ハードウェアとオペレーティングシステム間のインターフェイスを提供し、グラフィカルな操作インターフェイスを提供します。最も重要なのはGPTパーティションテーブルを導入し、2T以上のハードディスクをサポートし、ハードディスクのパーティションが制限されないことです。

### BIOSとUEFIの違い
- BIOSは16ビットアセンブリ言語で書かれ、実モード（メモリアドレッシング方式は16ビットセグメントレジスタの内容を16（10H）倍してセグメントベースアドレスとし、16ビットのオフセットアドレスを加えて20ビットの物理アドレスを形成する）でしか動作できず、アクセス可能なメモリ空間は1MBで、文字操作インターフェイスのみをサポートします。
- UEFIは32ビットまたは64ビットのC言語で書かれ、実モードの制限を突破し、最大のアドレッシング空間に到達し、グラフィカルな操作インターフェイスをサポートし、ファイル方式で情報を保存し、GPTパーティションブートをサポートし、新しいシステムとハードウェアの組み合わせに適しています。

### BIOS+MBRとUEFI+GPT
- 起動 → BIOS初期化 → BIOS自己診断 → オペレーティングシステムのブート → システムに入る
- 起動 → UEFI初期化 → オペレーティングシステムのブート → システムに入る

MSDN（Microsoft Developer Network）は、WindowsはBIOS+MBRまたはUEFI+GPTの組み合わせでしかインストールできず、BIOS+GPTおよびUEFI+MBRは許可されていないと指摘しています。ただし、BIOS+GPT+GRUBでLinuxをブートすることは可能です。


### 1.1.4 管理パーティション
#### ブロックデバイスの列挙
コマンド `lsblk` を使用してブロックデバイスを列挙できます。以下はよく使用されるオプションです。

- `-a` または `--all`：すべてのデバイス情報を出力します
- `-b` または `--bytes`：デバイスサイズをバイト単位で表示します
- `-d` または `--nodeps`：パーティション情報を表示しません
- `-e <list>` または `--exclude <list>`：主デバイス番号でデバイスを除外します
- `-f` または `--fs`：ファイルシステムを表示します
- `-i` または `--ascii`：ASCII文字のみで出力します
- `-I <list>` または `--include <list>`：指定したデバイスのみを表示します
- `-J` または `--json`：出力をJSON形式で表示します
- `-l` または `--list`：リスト形式で表示します
- `-T` または `--tree`：ツリー構造で表示します（デフォルト）
- `-m` または `--perms`：所有者、グループ、およびパーミッションを表示します
- `-n` または `--noheadings`：ヘッダーを表示しません
- `-o <list>` または `--output <list>`：指定した列のみを表示します
- `-O` または `--output-all`：すべての列を表示します
- `-p` または `--paths`：デバイスのフルパスを表示します
- `-P` または `--pairs`：キーと値の形式で表示します
- `-r` または `--raw`：そのまま出力します
- `-s` または `--inverse`：関連情報を逆に表示します
- `-S` または `--scsi`：SCSIデバイス（小型コンピュータインターフェイスデバイス）を表示します
- `-t` または `--topology`：トポロジ情報を表示します

#### よく使用されるフィールド
- `NAME`：デバイス名
- `MAJ:MIN`：主デバイス番号：副デバイス番号
- `RM`：リムーバブルデバイスかどうか
- `SIZE`：デバイス容量
- `RO`：読み取り専用デバイスかどうか
- `TYPE`：デバイスタイプ
- `MOUNTPOINT`：マウントポイント

#### 例: デバイスを確認
```bash
[root@rocky86 ~]# lsblk
NAME       MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda           8:0    0 200G  0 disk 
├─sda1        8:1    0   1G  0 part /boot
└─sda2        8:2    0 199G  0 part 
 ├─rl-root 253:0    0   70G  0 lvm /
 ├─rl-swap 253:1    0   2G  0 lvm [SWAP]
 └─rl-home 253:2    0 127G  0 lvm /home
sr0          11:0    1 10.5G  0 rom  
```

フルパスを表示するには、次のコマンドを使用します。
```bash
[root@rocky86 ~]# lsblk -p
NAME                   MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
/dev/sda                  8:0    0 200G  0 disk 
├─/dev/sda1               8:1    0   1G  0 part /boot
└─/dev/sda2               8:2    0 199G  0 part 
 ├─/dev/mapper/rl-root 253:0    0   70G  0 lvm /
 ├─/dev/mapper/rl-swap 253:1    0   2G  0 lvm [SWAP]
 └─/dev/mapper/rl-home 253:2    0 127G  0 lvm /home
/dev/sr0                 11:0    1 10.5G  0 rom 
```

ファイルシステムを表示するには、次のコマンドを使用します。
```bash
[root@rocky86 ~]# lsblk -f
NAME       FSTYPE     LABEL               UUID                                 
  MOUNTPOINT
sda                                                                               
  
├─sda1     xfs                             94a73757-555a-4d2b-8153-f54277c4c50d 
  /boot
└─sda2     LVM2_member                     qLmfIa-YvfP-3Du3-dwVG-a0qM-eZRRuP3P80 
 ├─rl-root xfs                             bd1ab1fd-ee1c-4908-a7b3-e83a170adda9 
  /
 ├─rl-swap swap                             c6f13a3f-a2f3-4ba7-a591-879f476fdd1a 
  [SWAP]
 └─rl-home xfs                             22a09cff-b3f2-48c5-b251-c1c4af9b11b7 
  /home
sr0         iso9660     Rocky-8-6-x86_64-dvd 2022-05-15-21-06-44-00
```

#### パーティション作成コマンド
- `fdisk`：MBRパーティションを管理します
- `gdisk`：GPTパーティションを管理します
- `parted`：高度なパーティション操作が可能で、対話型または非対話型で使用できます
- `partprobe`：メモリ内のカーネルパーティションテーブルバージョンをリセットします（CentOS 6以外のバージョン5, 7, 8に適用）

### 1.1.4.1 パーティションツールfdiskとgdisk

#### fdisk
`fdisk`はMBR（マスターブートレコード）パーティションを管理するためのコマンドラインツールです。基本的な使用方法は以下の通りです。

```bash
fdisk [options] <disk>
fdisk [options] -l [<disk>]
```

#### gdisk
`gdisk`はGPT（GUIDパーティションテーブル）パーティションを管理するためのツールで、`fdisk`に類似しています。

```bash
gdisk [options] [device...]
```

#### よく使用されるオプション
- `-b` または `--sector-size <size>`：セクターサイズを指定します（デフォルトは512バイト）
- `-L` または `--color[=color]`：表示時にカラーを使用するかどうかを設定します（`auto`|`always`|`never`、デフォルトはカラー有効）
- `-l` または `--list`：パーティションリストを表示します
- `-o` または `--output <list>`：指定した列のみを表示します
- `-u` または `--units[=<unit>]`：表示単位を設定します（`cylinders`|`sectors`、デフォルトは`sectors`）
- `-s` または `--getsz`：デバイスに何セクターあるかを表示します
- `-t` または `--type type`：指定したタイプのパーティションテーブルのみを表示します
- `-C` または `--cylinders N`：シリンダー数を指定します
- `-H` または `--heads N`：ヘッド数を指定します
- `-S` または `--sectors N`：各トラックのセクター数を指定します

#### よく使用されるサブコマンド
- `p`：パーティションリストを出力します
- `t`：パーティションタイプを変更します
- `n`：新しいパーティションを作成します
- `d`：パーティションを削除します
- `v`：パーティションを検証します
- `u`：単位を変更します
- `w`：保存して終了します
- `q`：保存せずに終了します
- `x`：高度な機能（エキスパートモード）

#### 異なるパーティションタイプに使用できる列（`-o`オプションと組み合わせて使用）
- `gpt`：`Device Start End Sectors Size Type Type-UUID Attrs Name UUID`
- `dos`：`Device Start End Sectors Cylinders Size Type Id Attrs Boot End-C/H/S Start-C/H/S`
- `bsd`：`Slice Start End Sectors Cylinders Size Type Bsize Cpg Fsize`
- `sgi`：`Device Start End Sectors Cylinders Size Type Id Attrs`
- `sun`：`Device Start End Sectors Cylinders Size Type Id Flags`

#### 使用例
##### パーティションリストの表示
- すべてのデバイスを表示

```bash
[root@rocky86 ~]# fdisk -l
```

- 指定したデバイスを表示

```bash
[root@rocky86 ~]# fdisk -l /dev/sda
```

##### 指定した列を表示

```bash
[root@rocky86 ~]# fdisk -lo id,size,type /dev/sda
Disk /dev/sda: 200 GiB, 214748364800 bytes, 419430400 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x5b8e1003
Id Size Type
83   1G Linux
8e 199G Linux LVM
```

##### 新しいパーティションをカーネルが認識しているか確認

```bash
[root@rocky86 ~]# cat /proc/partitions
major minor  #blocks name
   8        0  209715200 sda
   8        1    1048576 sda1
   8        2  208665600 sda2
   8       16   20971520 sdb
  11        0   10950656 sr0
253        0   73400320 dm-0
......
```

#### gdiskの使用方法
`gdisk`コマンドは、GPTパーティションテーブルを管理するために使用されます。以下は基本的な使用例です。

```bash
gdisk [ -l ] device
```

##### よく使用されるサブコマンド
- `b`：パーティションテーブルを指定したファイルにバックアップ
- `c`：パーティション名を変更
- `d`：パーティションを削除
- `i`：パーティションの詳細情報を表示
- `l`：すべてのパーティションタイプをリスト
- `n`：新しいパーティションを作成
- `o`：新しいパーティションテーブルを作成
- `p`：パーティションを表示
- `q`：終了
- `r`：復元および変換オプション（専門家以外は使用しない）
- `s`：ソート
- `t`：パーティションタイプを変更（デフォルトは8300、通常パーティション）
- `v`：ディスクに問題がないか検出
- `w`：保存して終了
- `x`：追加機能（エキスパートモード）
- `?`：ヘルプを表示