主磁碟機上的 dd 命令錯誤 - 如何恢復資料?

主磁碟機上的 dd 命令錯誤 - 如何恢復資料?

好吧,發生了一件令人惱火的愚蠢的事情。我想將 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.iso541065216 字節,或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,很明顯分區表(可能還有引導分區上的所有資料)已被破壞。應該是gptdisklabel類型,分割區大小/類型錯誤。不幸的是,由於 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

我發現了幾個相關問題:

我已經安裝了該testdisk實用程序,看起來很有希望,但我想確保執行正確的步驟當計算機仍在運作時。如果我現在關閉它,它就不會再啟動,所以這裡是問題:

  • 從這種情況中恢復的最佳方法是什麼?
  • 如何將分割表恢復到先前的形式,以及如何重新建立/boot分割區?我正在使用最新的核心運行 Arch Linux。
  • 有什麼方法可以知道我的根分區的前 4 MB 中包含(和破壞了?)什麼內容?

編輯:根據 @WumpusQ.Wumbley 運行dumpe2fs命令的建議在此處添加更多資訊和詳細資訊。

基本輸出(前 50 行)dumpe2fshttps://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反向執行相同的操作,將部分良好的資料放回磁碟上,覆蓋現在存在的所有壞資料。

之後,您可能會發現自動恢復工具 ( fscktestdisk) 運作得夠好。如果沒有,您可以使用地圖來幫助手動恢復。使用 中的「空閒區塊」列表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

  1. 關閉計算機(立即)
  2. 使用救援系統啟動它。
  3. 運行testdisk以嘗試恢復您的資料。 (如果您有足夠的空間,請使用該圖像從設備中獲取圖像dd並運行testdisk

為什麼要立即關閉計算機?如果將建立一個新檔案(可能在 /run 中)或附加到(/var/log/...),那麼檔案系統需要查看現有的(壞!)資訊來決定將資料儲存在哪裡。當基於錯誤資訊做出此決定時,現有資料區塊被覆蓋的風險很高。這讓他們永遠迷失了。即使是像testdisk和 之類的工具也是如此photorec

相關內容