gpart destroyコマンドの挙動を確かめる
先日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