読者です 読者をやめる 読者になる 読者になる

😃 mattintosh note 📝

Hello Raspberry Pi!

🐧 parted と gdisk で GPT ディスクのパーティショニング

GPT ディスクの管理に gdisk を使うようになり、parted との違いがある程度わかってきたので比較なんかをちょっと書いてみようかと思いました。

用途によりますが、個人的には gdisk の方が使いやすいのではないかと思います。


本記事で使用しているバージョンを以下に記載します。環境によって動作が異なる可能性がありますので詳しくはマニュアルを参照してください。

  • Linux Mint 17
  • GPT fdisk (gdisk) version 0.8.8
  • parted (GNU parted) 2.3

用語に関しては使い方が間違っている部分もあるかと思います。また、ここで使用している HDD はやや破損している WD20EARS を使用しているためセクタ数などに異常があるかもしれません。


parted

対話モードで操作するときの流れです。

parted /dev/sdb
GNU Parted 2.3
Using /dev/sdb
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) mklabel gpt
Warning: The existing disk label on /dev/sdb will be destroyed and all data on this disk will be lost. Do you want to continue?
Yes/No? y                                                                 
(parted) mkpart
Partition name?  []?                                                      
File system type?  [ext2]?                                                
Start? 0G                                                                 
End? 32G                                                                  
(parted) p                                                                
Model: WDC WD20 EARS-00MVWB0 (scsi)
Disk /dev/sdb: 2000GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt

Number  Start   End     Size    File system  Name  Flags
 1      1049kB  32.0GB  32.0GB  ext4

(parted) q                                                                
Information: You may need to update /etc/fstab.

mklabel で gpt もしくは msdos なパーティションラベルを作成し、mkpart でパーティションを作成していきます。フォーマットも同時に可能な mkpartfs もありますがこちらは非推奨となっています。

デフォルトではアライメントタイプは optimal、ユニットは compact(MB 指定と可読性の高い表示)になっています。この場合、開始位置に 0 を指定するとアライメントが正しくないというエラーになります。これは 1 を指定するか、unit コマンドで単位を GB や % などに変更したり、開始位置の指定を 0G もしくは 0% などで指定するとことで開始位置が 2048s になりエラーが出なくなります。アライメントタイプは起動時のオプション -a minimal 等で変更ができます。

parted では -s オプションを使って非対話モードで処理することもできます。このオプションは sed -e のように1回のコマンドで複数の処理を分けて書くことができ、次の -s までが parted のコマンドになります。(対話モードでは名前無しのパーティションを作成できましたがこのモードではできないかもしれません。書式不明…)

# GPT パーティションラベルの作成
parted /dev/sdb -s mklabel gpt
# 新しいパーティションを作成
parted /dev/sdb -s mkpart untitled ext2 0G 32G
# ユニットをセクタに変更してパーティションテーブルを表示
parted /dev/sdb -s p -s unit s -s p

第1パーティションが 2048s から始まります。(ディスク情報は省略しています)

Number  Start   End        Size       File system  Name      Flags
 1      1049kB  32.0GB     32.0GB     ext4         untitled

Number  Start   End        Size       File system  Name      Flags
 1      2048s   62500863s  62498816s  ext4         untitled

-a minimal でアライメントタイプを変更した場合は 34s から始まります。終了位置はぴったり 32 GB になっていますがこれで正しいパフォーマンスが得られるかどうかはわかりません。

Number  Start   End        Size       File system  Name      Flags
 1      17.4kB  32.0GB     32.0GB                  untitled

Number  Start   End        Size       File system  Name      Flags
 1      34s     62500000s  62499967s               untitled

man には書かれていませんが parted は IEC での指定にも対応しており、Gi や GiB 等で指定できます。こちらの方が df -h したときに見栄えがいいかもしれません。

parted /dev/sdb \
  -s mklabel gpt \
  -s mkpart untitled ext2 0Gi 32Gi \
  -s mkpart untitled ext2 32Gi 100% \
  -s p \
  -s unit Gi -s p \
  -s unit s -s p
Number  Start      End          Size         File system  Name      Flags
 1      1049kB     34.4GB       34.4GB       ext4         untitled
 2      34.4GB     2000GB       1966GB       ext4         untitled

Number  Start      End          Size         File system  Name      Flags
 1      0.00GiB    32.0GiB      32.0GiB      ext4         untitled
 2      32.0GiB    1863GiB      1831GiB      ext4         untitled

Number  Start      End          Size         File system  Name      Flags
 1      2048s      67108863s    67106816s    ext4         untitled
 2      67108864s  3907028991s  3839920128s  ext4         untitled

パーティションラベルを msdos で作成した場合、mkpart の第1引数はパーティション名ではなくパーティションタイプ(primary|logical|extended)の指定になります。gdisk の方で書きますが parted はパーティション数が増えると計算が面倒になってきます。

parted /dev/sdb \
  -s mklabel msdos \
  -s mkpart primary 0G 32G \
  -s mkpart extended 32G 100% \
  -s mkpart logical 32G 64G \
  -s mkpart logical 64G 96G \
  -s p free
Number  Start   End     Size    Type      File system  Flags
        32.3kB  1049kB  1016kB            Free Space
 1      1049kB  32.0GB  32.0GB  primary   ext4
 2      32.0GB  2000GB  1968GB  extended               lba
 5      32.0GB  64.0GB  32.0GB  logical
 6      64.0GB  96.0GB  32.0GB  logical
        96.0GB  2000GB  1904GB            Free Space
        2000GB  2000GB  90.1kB            Free Space

LVM 用パーティション作成ならこんな感じでしょうか。スクリプトモードだとパーティション名を付けないといけないのが面倒ですね…。

parted /dev/sdb -s mklabel gpt -s mkpart untitled ext2 0% 100% -s set 1 lvm on

スクリプトモードでは -8G といった指定がオプションと勘違いされるようなので後方相対位置指定(?)はできないようです。

gdisk

fdisk の GPT 版なので fdisk を使用したことがある人なら操作方法はほとんど同じだと思います。Curses 版の cgdisk やスクリプト版の sgdisk もあります。

以下は gdisk でディスクの初期化とパーティションの作成を行うときの流れです。

gdisk /dev/sdb
GPT fdisk (gdisk) version 0.8.8

Partition table scan:
  MBR: not present
  BSD: not present
  APM: not present
  GPT: not present

Creating new GPT entries.

Command (? for help): o
This option deletes all partitions and creates a new protective MBR.
Proceed? (Y/N): y
Command (? for help): n
Partition number (1-128, default 1): 
First sector (34-15523806, default = 2048) or {+-}size{KMGTP}:
Last sector (2048-15523806, default = 15523806) or {+-}size{KMGTP}:
Current type is 'Linux filesystem'
Hex code or GUID (L to show codes, Enter = 8300):
Changed type of partition to 'Linux filesystem'

Command (? for help): p
Disk /dev/sdb: 3907029168 sectors, 1.8 TiB
Logical sector size: 512 bytes
Disk identifier (GUID): 89E13014-DADD-4DF3-A8BF-3C23AC8DD233
Partition table holds up to 128 entries
First usable sector is 34, last usable sector is 3907029134
Partitions will be aligned on 2048-sector boundaries
Total free space is 3839920237 sectors (1.8 TiB)

Number  Start (sector)    End (sector)  Size       Code  Name
   1            2048        67110911   32.0 GiB    8300  Linux filesystem

Command (? for help): w
Final checks complete. About to write GPT data. THIS WILL OVERWRITE EXISTING
PARTITIONS!!

Do you want to proceed? (Y/N): y
OK; writing new GUID partition table (GPT) to /dev/sdb.
The operation has completed successfully.

gdisk の良いところは開始・終了位置の範囲と規定値を表示してくれたり、終了位置を +1G のように相対指定できることです。parted では終了位置を直接指定するため、例えばパーティションサイズを 32 GiB にぴったり合わせたい場合は事前に計算しておく必要があり、パーティションが増えれば増えるほど面倒になっていきますが gdisk は + を付けてサイズ指定するだけなのでとても簡単です。

そして重要なのが parted はコマンド結果をすぐに書き込みますが、gdisk では w コマンドを実行した後、最終確認に回答してから書き込みを行うことです(それまでは p コマンドで処理予定を表示できます)。誤って既存パーティションを破損してしまう心配が少なくて済みます。

x や r でエキスパートモードに入り、アライメント値や GUID を変更したりパーティションテーブルのバックアップなどもできます。

対話モードでは "Linux filesystem" のようにパーティション名が自動設定されます(c コマンドで何も入力しなければ削除できます)。sgdisk や cgdisk では名前が付きません。

次に、gdisk のコマンドライン向けコマンド sgdisk です。sgdisk では -n <パーティション番号>:<開始>:<終了> という書式でパーティション番号とサイズを指定します。開始と終了の値は対話モード同様に省略可能です。parted -s と同様に -n などのオプションも複数回使用できます。

# パーティションラベルの完全破壊
sgdisk -Z /dev/sdb
# GPT ラベルの書き込み(省略可)
sgdisk -o /dev/sdb
# 第1パーティションに先頭(2048s)から 32 GiB 分使用、第2パーティションに空き領域全て使用し名前を "Free Space" に
sgdisk \
  -n 1::+32G \
  -n 2::: \
  -c 2:"Free Space" /dev/sdb
# パーティションテーブルを表示
sgdisk -p /dev/sdb
Number  Start (sector)    End (sector)  Size       Code  Name
   1            2048        67110911   32.0 GiB    8300  
   2        67110912      3907029134   1.8 TiB     8300  Free Space

parted で終了位置を 32 GiB にした場合と比較してみます。parted は絶対位置指定なので第1パーティションのサイズがアライメント分で 1 MiB 少なくなります。

gdisk

Number  Start     End         Size        File system  Name        Flags
 1      1.00MiB   32769MiB    32768MiB    ext4
 2      32769MiB  1907729MiB  1874960MiB               Free Space

parted

Number  Start     End         Size        File system  Name        Flags
 1      1.00MiB   32768MiB    32767MiB    ext4
 2      32768MiB  1907729MiB  1874961MiB  ext4

LVM 用はこんな感じでしょうか。parted に比べてシンプルです。

sgdisk -o -n 1::: -t 1:8e00 /dev/sdb

お遊びですが、gdisk でもヒアドキュメントで回答を予測してパーティション作成ができるようです。

gdisk /dev/sdb <<!
o
y
n




w
y
!

parted については以下の点において誤りがあるかもしれません。とりあえずこの辺は gdisk を使えば全て解決するので時間があったらまた調べようと思います。

今回試してみた parted と gdisk の比較表です。gdisk のバックアップ関連はまだマニュアルを熟読していないので修復機能があるかどうかはわかりません。

  parted gdisk
アライメント調整 ○ ○
アライメント指定方法 none
cylinder
minimal
optimal
1-65536s
(デフォルト:2048s)
開始・終了位置指定 要 不要
絶対位置指定 ○ ○
開始位置からの相対位置指定 × ○
ディスク後方からの相対位置指定 ○ ○
SI 指定 ○ ×
IEC 指定 ○ ○
% 指定 ○ ×
MBR 対応 ○ ×
コマンドライン(スクリプト)モード ○ sgdisk で対応
パーティションのリサイズ ○ ○
パーティションテーブルのバックアップ・リストア × ○
パーテイションの修復 ○ ?

自分は今のところこんな感じで使い分けています。

  • パーティションを理想のサイズで綺麗に並べたいなら gdisk
  • SI でサイズを指定したり、2等分4等分とかしたいなら parted

今回、32 GiB といったサイズの指定例を書きましたが、こういったサイズはあまりおすすめできません。というのは大抵のストレージは 10 の n 乗というサイズで表記されているので、例えば 32 GiB(34.4 GB)のパーティションは 32 GB の USB フラッシュメモリには収まらず、ストレージの移行やバックアップの際に無駄な作業が生じる可能性があります。このことを考えると IEC 指定の gdisk は使い難いかもしれません。

ま、パーティションの区切り方は個人の自由ですので…。SI と IEC の計算は numfmt コマンドを用いると楽です(coreutils パッケージに含まれています)。

操作を間違えると簡単にパーティションが吹っ飛ぶので使い方がよくわからないときは仮想マシンなどで練習することをおすすめします。