好吧,發生了一件令人惱火的愚蠢的事情。我想將 Arch Linux ISO 檔案複製到我的 USB 隨身碟,但很匆忙,不小心輸入了我的主磁碟機作為參數of
。
詳細資訊如下:
$ sudo dd bs=4MB if=archlinux-2017.08.01-x86_64.iso of=/dev/nvme1n1
/dev/nvme1n1
本來應該/dev/sdb
。
我的主磁碟機/dev/nvme1n1
包含兩個分割區:
- 1 個 512 MB EFI 啟動分割區
- 一個 ext4 分割區跨越 1 TB 硬碟的其餘部分
檔案大小為archlinux-2017.08.01-x86_64.iso
541065216 字節,或516MB
計算機仍在運行並且似乎工作正常,並且我有lsblk
和的輸出df -h
前運行dd
命令。輸出是一模一樣就像我現在運行命令時一樣。我假設因為資料被快取:
$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
nvme1n1 259:5 0 931.5G 0 disk
├─nvme1n1p1 259:6 0 512M 0 part /boot
└─nvme1n1p2 259:7 0 931G 0 part /
$ df -h
Filesystem Size Used Avail Use% Mounted on
/dev/nvme1n1p2 916G 22G 848G 3% /
/dev/nvme1n1p1 511M 36M 476M 7% /boot
ls /boot
仍然列印目錄內容(可能是快取的資訊),但文件內容已損壞,並且正在運行ls /boot/EFI
,或者ls /boot/loader
用隨機字元填充螢幕,包括大量Input/output error
.
以下是更多資訊:
$ cat /proc/partitions
major minor #blocks name
259 5 976762584 nvme1n1
259 6 524288 nvme1n1p1
259 7 976237255 nvme1n1p2
$ sudo fdisk -l /dev/nvme1n1
Disk /dev/nvme1n1: 931.5 GiB, 1000204886016 bytes, 1953525168 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: 0x282bad86
Device Boot Start End Sectors Size Id Type
/dev/nvme1n1p1 * 0 1056767 1056768 516M 0 Empty
/dev/nvme1n1p2 164 131235 131072 64M ef EFI (FAT-12/16/32)
查看 的輸出fdisk
,很明顯分區表(可能還有引導分區上的所有資料)已被破壞。應該是gpt
disklabel類型,分割區大小/類型錯誤。不幸的是,由於 ISO 檔案大小 (516 MB),它也覆蓋了我的根分割區的前 4 MB。
輸出略有不同gdisk
:
$ sudo gdisk /dev/nvme1n1
# selected GPT when asked "Found valid MBR and GPT. Which do you want to use?"
Command (? for help): p
Disk /dev/nvme1n1: 1953525168 sectors, 931.5 GiB
Model: Samsung SSD 960 EVO 1TB
Sector size (logical/physical): 512/512 bytes
Disk identifier (GUID): <guid>
Partition table holds up to 248 entries
Main partition table begins at sector 2 and ends at sector 63
First usable sector is 64, last usable sector is 1056704
Partitions will be aligned on 8-sector boundaries
Total free space is 1 sectors (512 bytes)
Number Start (sector) End (sector) Size Code Name
2 164 131235 64.0 MiB 0700 ISOHybrid1
我發現了幾個相關問題:
- https://askubuntu.com/questions/94421/is-there-a-way-to-recover-files-from-a-storage-device-partially-overwriting-with
- 不小心用dd覆蓋了錯誤的磁碟,如何恢復?
我已經安裝了該testdisk
實用程序,看起來很有希望,但我想確保執行正確的步驟當計算機仍在運作時。如果我現在關閉它,它就不會再啟動,所以這裡是問題:
- 從這種情況中恢復的最佳方法是什麼?
- 如何將分割表恢復到先前的形式,以及如何重新建立/boot分割區?我正在使用最新的核心運行 Arch Linux。
- 有什麼方法可以知道我的根分區的前 4 MB 中包含(和破壞了?)什麼內容?
編輯:根據 @WumpusQ.Wumbley 運行dumpe2fs
命令的建議在此處添加更多資訊和詳細資訊。
基本輸出(前 50 行)dumpe2fs
:https://pastebin.com/fBuFRQfE
對我來說,它看起來很正常,甚至檔案系統幻數 ( 0xEF53
) 也是正確的。
接下來是Group 0
:
Group 0: (Blocks 0-32767) csum 0x9569 [ITABLE_ZEROED]
Primary superblock at 0, Group descriptors at 1-117
Reserved GDT blocks at 118-1141
Block bitmap at 1142 (+1142)
Inode bitmap at 1158 (+1158)
Inode table at 1174-1685 (+1174)
21349 free blocks, 8177 free inodes, 2 directories, 8177 unused inodes
Free blocks: 11419-32767
Free inodes: 16-8192
然後後面有很多組說[...]8192 free inodes, 0 directories, 8192 unused inodes [...]
The first group thatactual reports some paths is not Until Group 3648
,或大約 25,000 行之後:
Group 3648: (Blocks 119537664-119570431) csum 0xa9ea [ITABLE_ZEROED]
Block bitmap at 119537664 (+0)
Inode bitmap at 119537680 (+16)
Inode table at 119537696-119538207 (+32)
23930 free blocks, 1670 free inodes, 614 directories, 1670 unused inodes
Free blocks: 119546502-119570431
Free inodes: 29890939-29892608
整個檔案系統中有很多備份超級塊:
$ sudo dumpe2fs /dev/nvme1n1p2 | grep -i superblock | wc -l
dumpe2fs 1.43.5 (04-Aug-2017)
19
答案1
我假設分區表和啟動分區可以輕鬆重新創建,所以我將重點放在 ext4 分區。
文件系統的佈局在某種程度上取決於創建它時使用的選項。我將描述常見情況。您可以透過在設備上運行來查看這是否與您的匹配dumpe2fs
(這將有望在快取中找到所有頂級元數據,而不是從磁碟讀取)。
ext4 檔案系統的正常區塊大小是 4096 字節,因此您遺失了 1024 個區塊。
第一個被覆蓋的是區塊 0,即主要超級區塊。這本身不是問題,因為有備份超級區塊。之後是群組描述符表,它也在檔案系統內有備份。
然後是區塊位圖和索引節點位圖。這就是消息開始變得更糟的地方。如果其中任何一個低於區塊 1024(它們很可能是),您就遺失了有關正在使用哪些 inode 和區塊的資訊。此資訊是多餘的,將由 fsck 根據它在遍歷所有目錄和 inode 時發現的內容(如果它們完好無損)進行重建。
但接下來是 inode 表,在這裡你可能已經遺失了很多 inode,包括根目錄、日誌和其他特殊 inode。如果能把它們拿回來就好了。顯然,根目錄至少仍然有效,否則您嘗試運行的幾乎所有命令都將失敗。
如果您現在運行dd if=/dev/nvme1n1p2 of=/some/external/device bs=4096 count=1024
,您將獲得當前快取中所有內容的備份副本,其中包含未快取區塊的錯誤資料。然後,在啟動救援磁碟後,您可以dd
反向執行相同的操作,將部分良好的資料放回磁碟上,覆蓋現在存在的所有壞資料。
之後,您可能會發現自動恢復工具 ( fsck
、testdisk
) 運作得夠好。如果沒有,您可以使用地圖來幫助手動恢復。使用 中的「空閒區塊」列表dumpe2fs
,您知道要忽略哪些區塊。
您遺失的大部分內容可能是索引節點。實際上很可能您沒有文件內容在磁碟的前 4MB 中。 (我mkfs.ext4
在 1TB 映像檔上沒有任何選項地運行,第一個非元資料區塊結果是區塊 9249)
您設法恢復的每個索引節點都將識別整個檔案的資料塊。這些資料塊可能位於整個磁碟上,不一定位於附近。
第二天
Pastebin 上發布的轉儲揭示了好消息:
Group 0: (Blocks 0-32767) csum 0x9569 [ITABLE_ZEROED]
Primary superblock at 0, Group descriptors at 1-117
Reserved GDT blocks at 118-1141
Block bitmap at 1142 (+1142)
Inode bitmap at 1158 (+1158)
Inode table at 1174-1685 (+1174)
21349 free blocks, 8177 free inodes, 2 directories, 8177 unused inodes
Free blocks: 11419-32767
Free inodes: 16-8192
由於我們認為檔案系統開頭只有 4MB 被覆蓋,因此我們只需要擔心區塊 0-1023。保留的 GDT 塊一直到塊 1141!這種損壞應該透過簡單的修復e2fsck -b $backup_superblock_number
(重新啟動後)。你至少可以嘗試一下,-n
看看它是怎麼想的。
答案2
如果磁碟使用GPT,則可以使用磁碟末尾的備份GPT資料來還原分割區表。你可以用gdisk
;來做到這一點看gdisk
有關資料恢復的文檔了解詳情。簡而言之:當您gdisk
在磁碟上啟動時,它將大概注意損壞情況並詢問您是否要使用備份 GPT 資料或 MBR 資料。如果您選擇 GPT 選項然後寫入更改,分割區表將被修復。如果gdisk
不詢問要使用哪個分割區表,您仍然可以使用c
還原和轉換功能表上的選項來載入備份表。
/sys/block/nvme1n1/nvme1n1p1/start
如果失敗,您仍然可以使用和/sys/block/nvme1n1/nvme1n1p1/size
文件中的資料(與 類似)重新建立分區表(或至少是分區的起點和終點)/dev/nvme1n1p2
。但是,如果您求助於這些數據,那麼您必須不是關閉計算機,這與 hek2mgl 的建議相反。也就是說,hek2mgl 並沒有錯,繼續使用目前狀態的磁碟可能會帶來使情況變得更糟的風險。總的來說,我想說最好的妥協是嘗試盡快修復分割區表問題,然後關閉並從緊急磁碟修復檔案系統問題。
不幸的是,你的 ESP 已經完蛋了。考慮到你的磁碟佈局,我猜你安裝了 ESP/boot
並將核心儲存在那裡。因此,您需要使用某種chroot
或其他方式重新安裝內核軟體包。您的引導程式或引導管理員也是如此。
答案3
- 關閉計算機(立即)
- 使用救援系統啟動它。
- 運行
testdisk
以嘗試恢復您的資料。 (如果您有足夠的空間,請使用該圖像從設備中獲取圖像dd
並運行testdisk
)
為什麼要立即關閉計算機?如果將建立一個新檔案(可能在 /run 中)或附加到(/var/log/...),那麼檔案系統需要查看現有的(壞!)資訊來決定將資料儲存在哪裡。當基於錯誤資訊做出此決定時,現有資料區塊被覆蓋的風險很高。這讓他們永遠迷失了。即使是像testdisk
和 之類的工具也是如此photorec
。