誤ってパーティションテーブル (LBA 0) を消して(0クリアして)しまった場合の対処
raspberry pi のイメージを PC でバックアップしたとき、 SD CARD のパーティションテーブル(LBA 0)を消してしまった。
もちろん意図して消した訳ではない。 むしろ、消していることに気が付かずに、 SD CARD を raspberry pi に戻して再起動させた時に起動しなくなっていて、 意味が分からずかなり焦った。
起動しない原因がパーティションテーブルを消していたことだと気付くのに、 かなりの時間を要した。
そんな訳で、パーティションテーブルを復旧させる方法を説明する。
パーティションテーブル復旧方法
パーティションテーブル復旧方法の手順は次の通り。
- 物理パーティションの場所を特定する
- マウントして中身を確認する
- PARTUUID を復旧する
- fsck する
以降、それぞれの対応手順を説明する。
復旧処理中にデータを壊してしまう可能性があるため、 以降では バックアップを取ったイメージファイルに対して処理 を行なうものとする。
物理パーティションの場所を特定する
パーティションテーブルの主な役割は、 物理パーティションの場所を示すことである。
つまり、物理パーティションがどこにあるのかを調べなければならない。
この作業を行なってくれるツールとして testdisk がある。
testdisk に関しては、次の URL を参考にすること。
https://www.atmarkit.co.jp/flinux/rensai/linuxtips/991testdisk.html
上記 URL の手順と違うのは、 起動する際のコマンドオプションとして 以下のようにバックアップファイル名を指定する。
$ sudo testdisk /log /backupfile.img
testdisk で物理パーティションが見つからなかった場合は、次の方法を試す。
testdisk で物理パーティションを見つけられなかった場合
raspberry pi をインストールする際に使用した元のイメージファイルに対し fdisk する。
$ fdisk /org_image.img
パーティション情報を確認する。
Command (m for help): p Disk org_image.img: 1.75 GiB, 1858076672 bytes, 3629056 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: 0x067e19d7 Device Boot Start End Sectors Size Id Type org_image.img1 8192 532479 524288 256M c W95 org_image.img2 532480 3629055 3096576 1.5G 83 Linu
このパーティション情報を元に、バックアップファイルのパーティション情報を設定する。
$ fdisk /backupfile.img
ただし、パーティション 2 の End 位置は、オリジナルと異なる。 基本的に End 位置は、最大サイズになるように設定しておけば良い。
マウント
パーティションが見付かったら、そのパーティションをマウントする。
マウントする場合、次のコマンドを実行する。
$ sudo mkdir -p /mnt/recovery $ sudo mount -o loop,offset=272629760 /backupfile.img /mnt/recovery
ここで offset には、パーティションの開始セクタ番号 x 512 を指定する。
PARTUUID を復旧する
物理パーティションの情報が復旧できても、 PARTUUID が復旧できていないと、ブートできない。
そこで、 fstab に記載されている PARTUUID を確認する。
$ cat /mnt/recovery/etc/fstab PARTUUID=3729482f-01 /boot vfat defaults 0 2 PARTUUID=3729482f-02 / ext4 defaults,noatime 0 1
この 3729482f を PARTUUID に設定する。
$ fdisk /backupfile.img Welcome to fdisk (util-linux 2.34). Changes will remain in memory only, until you decide to write them. Be careful before using the write command. Command (m for help): x Expert command (m for help): i Enter the new disk identifier: 0x3729482f Expert command (m for help): r Command (m for help): w
fsck
念のため fsck を掛けてファイルが壊れていないか確認する。
マウントされていると fsck を掛けられないので解除する。
$ df Filesystem 1K-blocks Used Available Use% Mounted on /dev/loop0 15022248 12407452 1972256 87% /mnt/recovery $ sudo umount /dev/loop0
次に loop デバイスにイメージを設定。
$ sudo losetup /dev/loop0 --offset 272629760 /backupfile.img
そして loop デバイスを fsck。
$ sudo fsck -a /dev/loop0
バックアップファイルを SD カードに書き戻す
以上で、バックアップファイル内のパーティションテーブルの復旧が出来たので、 SDカードにバックアップファイルを書き戻す。
なお、 fsck で問題が出ていなかった場合、LBA 0 だけ書き戻せば良い。
以上。