先日FreeBSDでGPTを使うテストをしたときに、ディスクのパーティションテーブルが空ではなくgpart createがエラーになったので、まずはgpart destroy -Fで既存のパーティションテーブルを破棄する、ということがありました。

このgpart destroy -Fって、gpart(8)のマニュアルを見ても「パーティションテーブルをdestroyする」としか書かれていません。実際には何をやっているのか気になったので、少し試してみました。

今回は、PCにつないだ500GBのad7を使います。

まず、ディスクの先頭64セクタをゼロで埋めます。GPTのサイズは34セクタですが、少し余裕を見て64セクタにしておきます。

# dd if=/dev/zero of=/dev/ad7 count=64
64+0 records in
64+0 records out
32768 bytes transferred in 0.010082 secs (3250147 bytes/sec)

GPTは、ディスクの末尾にもバックアップのセカンダリGPTを持っているので、末尾64セクタもクリアしておきましょう。ちなみにこのディスクのサイズは976773168セクタです。

# dd if=/dev/zero of=/dev/ad7 seek=976773104
dd: /dev/ad7: end of device
65+0 records in
64+0 records out
32768 bytes transferred in 0.013114 secs (2498708 bytes/sec)

では、gpart createでパーティションテーブルを作ります。とりあえず、全領域をfreebsd-ufsに割り当てておきます。

# gpart create -s GPT ad7
ad7 created
# gpart add -t freebsd-ufs ad7
ad7p1 added

ここで、ディスクの先頭64セクタと末尾64セクタの内容をダンプしてファイルに保管しておきます。

# dd if=/dev/ad7 count=64 | hd > first64.before
64+0 records in
64+0 records out
32768 bytes transferred in 0.004338 secs (7553666 bytes/sec)
# dd if=/dev/ad7 skip=976773104 | hd > last64.before
64+0 records in
64+0 records out
32768 bytes transferred in 0.004581 secs (7153063 bytes/sec)

次はdestroyでGPTを「破壊」します。やはり-Fオプションを付けないとダメなようです。

# gpart destroy ad7
gpart: Device busy
# gpart destroy -F ad7
ad7 destroyed

破壊後の先頭64セクタと末尾64セクタの内容を、同様にダンプしてファイルに保管します。

# dd if=/dev/ad7 count=64 | hd > first64.after
64+0 records in
64+0 records out
32768 bytes transferred in 0.004482 secs (7310972 bytes/sec)
# dd if=/dev/ad7 skip=976773104 | hd > last64.after
64+0 records in
64+0 records out
32768 bytes transferred in 0.004557 secs (7190862 bytes/sec)

では、先頭64セクタの前後を比較してみましょう。

# diff -c first64.before first64.after
*** first64.before      Sun Oct 23 17:09:57 2011
--- first64.after       Sun Oct 23 17:13:21 2011
***************
*** 1,18 ****
  00000000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
  *
- 000001b0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 01  |................|
- 000001c0  01 00 ee ff ff ff 01 00  00 00 2f 60 38 3a 00 00  |........../`8:..|
- 000001d0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
- *
- 000001f0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 55 aa  |..............U.|
- 00000200  45 46 49 20 50 41 52 54  00 00 01 00 5c 00 00 00  |EFI PART....\...|
- 00000210  88 fe 14 ed 00 00 00 00  01 00 00 00 00 00 00 00  |................|
- 00000220  2f 60 38 3a 00 00 00 00  22 00 00 00 00 00 00 00  |/`8:....".......|
- 00000230  0e 60 38 3a 00 00 00 00  7d dc 0a 4b 4e fd e0 11  |.`8:....}..KN...|
- 00000240  a9 b1 00 1f c6 e3 48 e9  02 00 00 00 00 00 00 00  |......H.........|
- 00000250  80 00 00 00 80 00 00 00  53 a2 ef d1 00 00 00 00  |........S.......|
- 00000260  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
- *
  00000400  b6 7c 6e 51 cf 6e d6 11  8f f8 00 02 2d 09 71 2b  |.|nQ.n......-.q+|
  00000410  e0 ed 64 4e 4e fd e0 11  a9 b1 00 1f c6 e3 48 e9  |..dNN.........H.|
  00000420  22 00 00 00 00 00 00 00  0e 60 38 3a 00 00 00 00  |"........`8:....|
--- 1,5 ----

先頭に「-」がついているのが、ダンプから消えた行です。セクタ0とセクタ1は全てゼロに戻されたようです。

1be(10進で446)~1cd(461)の16バイトはMBRの第1パーティションで、GPTのProtective MBRを表すパーティションタイプ0xEEが入っていたのが見えますが、ざっくり削除(ゼロクリア)されています。

200(512)~25b(603)までの92バイトがプライマリーGPTヘッダですが、ここもすべてゼロクリアされています。

400(1024)から先は第1パーティションのエントリーですが、ここは削除されずに残っています。最初の16バイトがFreeBSDのUFSを表すGUID、次の16バイトがパーティションごとにユニークなGUID、次の8バイトが最初のLBA(リトルエンディアンなので、16進で22、10進では34です)、次の8バイトが最後のLBAです(16進で3a38600eだから、10進で976773134。ディスクのサイズは976773168セクタですから、末尾の34セクタを除いたサイズが、きっちり割り当てられています)。

では、末尾の64セクタはどう変わったでしょうか。

# diff -c last64.before last64.after

あれれ、何も変化がありません。中身を見てみましょう。

# cat last64.before
00000000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00003e00  b6 7c 6e 51 cf 6e d6 11  8f f8 00 02 2d 09 71 2b  |.|nQ.n......-.q+|
00003e10  e0 ed 64 4e 4e fd e0 11  a9 b1 00 1f c6 e3 48 e9  |..dNN.........H.|
00003e20  22 00 00 00 00 00 00 00  0e 60 38 3a 00 00 00 00  |"........`8:....|
00003e30  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00007e00  45 46 49 20 50 41 52 54  00 00 01 00 5c 00 00 00  |EFI PART....\...|
00007e10  88 fc ae 56 00 00 00 00  2f 60 38 3a 00 00 00 00  |...V..../`8:....|
00007e20  01 00 00 00 00 00 00 00  22 00 00 00 00 00 00 00  |........".......|
00007e30  0e 60 38 3a 00 00 00 00  7d dc 0a 4b 4e fd e0 11  |.`8:....}..KN...|
00007e40  a9 b1 00 1f c6 e3 48 e9  0f 60 38 3a 00 00 00 00  |......H..`8:....|
00007e50  80 00 00 00 80 00 00 00  53 a2 ef d1 00 00 00 00  |........S.......|
00007e60  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00008000

3e00~3e2fは、GPTの第1パーティションのエントリーで、7e00~7e5cの92バイトはセカンダリGPTヘッダです。どちらもプライマリGPTと同じ情報が入っています。

セカンダリGPTは、プライマリが損傷したときにヘッダを復旧させるために存在しているようなので、本当にパーティションテーブルを削除したいのであれば、こちらも手動で(ddで)クリアしておいた方がよいかもしれません。

まとめておきましょう。gpart destroy -Fコマンドでは:

  • Protective MBRのパーティションテーブルはゼロクリアされる。
  • プライマリGPTヘッダはゼロクリアされる。
  • プライマリGPTのパーティションエントリーは、そのまま残骸が残る。
  • セカンダリGPTは、ヘッダ、パーティションエントリーとも、そのまま残骸が残る。場合によっては手動でクリアした方がよいかも。

※バージョンメモ

  • FreeBSD 8.2-RELEASE