先日、外付けディスクに新規作成したパーティションをext4で初期化しようとしたところ、"The resulting partition is not properly aligned for best performance."と言われたため、パーティションを切りなおそうと、partedで既存パーティションの削除・再作成を行おうとしました。
ところが、誤って異なるディスクに対してパーティション削除を行ってしまい、復旧する必要があったので、以下に記録しておきます。
誤ってパーティション削除
/dev/sdcに対してパーティション削除を行いたかったのですが、/dev/sdaに対して削除を行ってしまいました。
というのも、partedは引数無しで起動すると、デフォルトでは/dev/sdaが選択されるようです。
$ sudo parted GNU Parted 3.2 Using /dev/sda ←ここに/dev/sdaと表示されているのに見落とした Welcome to GNU Parted! Type 'help' to view a list of commands.
また、本来の対象ディスクも誤って削除したディスクもSeagate Expansion Deskだったために、違和感を覚えずに作業を進めてしまいました。
(parted) print free Model: Seagate Expansion Desk (scsi) Disk /dev/sda: 2000GB Sector size (logical/physical): 512B/4096B Partition Table: msdos Disk Flags: Number Start End Size Type File system Flags 32.3kB 1049kB 1016kB Free Space 1 1049kB 2000GB 2000GB primary ext4
partedのヘルプを確認しておくと、rmにパーティション番号を指定すると当該パーティションを削除できることが判ります。
(parted) help align-check TYPE N check partition N for TYPE(min|opt) alignment help [COMMAND] print general help, or help on COMMAND mklabel,mktable LABEL-TYPE create a new disklabel (partition table) mkpart PART-TYPE [FS-TYPE] START END make a partition name NUMBER NAME name partition NUMBER as NAME print [devices|free|list,all|NUMBER] display the partition table, available devices, free space, all found partitions, or a particular partition quit exit program rescue START END rescue a lost partition near START and END resizepart NUMBER END resize partition NUMBER rm NUMBER delete partition NUMBER select DEVICE choose the device to edit disk_set FLAG STATE change the FLAG on selected device disk_toggle [FLAG] toggle the state of FLAG on selected device set NUMBER FLAG STATE change the FLAG on partition NUMBER toggle [NUMBER [FLAG]] toggle the state of FLAG on partition NUMBER unit UNIT set the default unit to UNIT version display the version number and copyright information of GNU Parted
で、対象ディスクが異なっていることに気づかないまま、パーティション削除してしまったのです。が、何やらエラーメッセージが表示されました。「使用中のパーティションを書き換えたけど、カーネルにそれを通知できないから古いパーティションは使用中のまま残ってしまうぞ。追加の変更を行う前に再起動するべきだぞ。」みたいなことを言っています。ここで、対象ディスクを間違えていたことに気づいたため、Cancelを選択しました。
(parted) rm 1 Warning: Partition /dev/sda1 is being used. Are you sure you want to continue? Yes/No? y Error: Partition(s) 1 on /dev/sda have been written, but we have been unable to inform the kernel of the change, probably because it/they are in use. As a result, the old partition(s) will remain in use. You should reboot now before making further changes. Ignore/Cancel? c
が、すでに時遅し。全領域がFree Spaceとして認識されています。
(parted) print free Model: Seagate Expansion Desk (scsi) Disk /dev/sda: 2000GB Sector size (logical/physical): 512B/4096B Partition Table: msdos Disk Flags: Number Start End Size Type File system Flags 32.3kB 2000GB 2000GB Free Space
rescueコマンドで復旧を試行
先ほど叩いたpartedのrmコマンドは数秒とかからず実行されました。実データを削除するには短すぎますので、パーティションテーブルというか、管理情報のメタデータだけが変更されたと考えられます。故に、現状では復旧できる可能性はかなり高いはずです。
調べてみると、partedのマニュアルには間違えてrmコマンド叩いてもrescueコマンドで復旧できるようなことが書かれています。
Parted User’s Manual: rescue
間違えてrmを叩いてしまったpartedのセッションは開いたままですので、そこでrescueを実行してみます。rescueの引数に、ディスクのどこから復旧できるパーティションを探すのかを指定する必要があるので、全領域を指定する意味で0から2000Gを指定してみましたが、全領域がFree Spaceのままです。
(parted) rescue Start? 0 End? 2000G (parted) print free Model: Seagate Expansion Desk (scsi) Disk /dev/sda: 2000GB Sector size (logical/physical): 512B/4096B Partition Table: msdos Disk Flags: Number Start End Size Type File system Flags 32.3kB 2000GB 2000GB Free Space
続いて、引数の指定方法を変えて、0%から100%を指定してみましたが、状況は変わらず。
(parted) rescue Start? 0% End? 100% (parted) print free Model: Seagate Expansion Desk (scsi) Disk /dev/sda: 2000GB Sector size (logical/physical): 512B/4096B Partition Table: msdos Disk Flags: Number Start End Size Type File system Flags 32.3kB 2000GB 2000GB Free Space
誤ってrmを叩いたときに表示されたメッセージのことを思い出すと、カーネルが認識している情報とディスクの現状に齟齬があるためにrescueできないのかと思い、再起動*1してから再度rescueコマンドを叩いてみても状況は変わりませんでした。
testdiskで復旧
他の復旧手段を調べてみると、testdiskというツールがあるようです。Ubuntuでは標準ではインストールされていませんが、パッケージマネージャから導入可能です。
sudo apt install testdisk
testdiskを起動すると対話型UIとなっており、基本的には画面の指示通り選択するだけです。最後に再起動したところ、無事復旧できたようで元のデータにアクセスできました。
スクリーンショットを撮っていないので雑な説明ですが、testdiskのUIで迷う点があるとすればPartition table typeの選択でIntelを選ぶことくらいでしょうか。
なお、復旧後のディスクにparted -lを叩いてみると、ディスクの外側にパーティションがあるみたいなエラーメッセージが表示されました。データにはアクセスできても、管理情報の一部は不完全な状態なのかもしれません。この状態で書き込み続けるのは怖いので、いったん別のディスクに復旧したデータを移動したうえで、初期化しなおしてからデータを書き戻した方が良さそうです。
まとめ
- partedを引数無しで起動すると、デフォルトで/dev/sdaが対象ディスクとして選択されているので、誤操作に注意が必要
- partedで誤ってrmしてもrescueで復旧ができることもあるらしい
- partedのrescueが上手く機能しなくても、testdiskで復旧できることがある
以上。
*1:当該ディスクが自動マウントされないよう、再起動前にfstabを編集しています。