Hard-Disk

如何通過 ddrescue 恢復嘗試找出哪些文件失去了?

  • August 9, 2021

我正在從 1 TB 故障驅動器中搶救數據(在更換硬碟的過程中被詢問?)。我已經ddrescue從系統救援 USB 完成了 191 個錯誤中的錯誤大小為 557568 B,可能全部都在/home(我假設它所謂的“錯誤”不是壞扇區,而是它們的連續序列)。

現在,我看到的幾個指南建議e2fsck在新磁碟上做,我希望這會以某種方式發現某些文件已被分配“空白扇區/塊”,至少知道哪些文件無法保存所有的。但是根本沒有發現任何錯誤(我執行它-y並沒有確保我沒有錯過任何東西)。現在我用 再次執行它-c,但到目前為止 95% 沒有發現錯誤;我想我有一個新驅動器,裡面有一些看起來很正常的文件,裡面有零塊或隨機片段,直到我用相應的軟體打開它們,或者 Linux Mint 需要它們之前都無法檢測到。

我可以對舊/新驅動器執行任何操作以獲得可能損壞的文件列表嗎?我不知道它們可能有多少,因為 191 可以跨越文件,但至少總大小不大;我最關心的是一大堆老家庭照片和影片(每個 1+ MB),其餘的可能無關緊要或最近備份。

更新:e2fsck 的新通行證確實提供了一些我一無所知的新東西:

Block bitmap differences:  +231216947 +(231216964--231216965) +231216970 +231217707 +231217852 +(231217870--231217871) +231218486
Fix<y>? yes
Free blocks count wrong for group #7056 (497, counted=488).                    
Fix<y>? yes
Free blocks count wrong (44259598, counted=44259589).
Fix<y>? yes

你需要所有遇到的壞塊的塊號(ddrescue應該給你一個列表,我希望你保存了它),然後你需要找出哪些文件使用了這些塊(參見例如here)。如果有很多壞塊,您可能需要編寫腳本。

e2fsck沒有幫助,它只是檢查文件系統本身的一致性,因此它只會對包含“管理”文件系統資訊的壞塊進行操作。

文件中的壞塊只是空的。

編輯

好的,讓我們弄清楚塊大小的東西。讓我們用 512 字節的設備塊製作一個試用文件系統:

$ dd if=/dev/zero of=fs bs=512 count=200
$ /sbin/mke2fs fs

$ ll fs
-rw-r--r-- 1 dirk dirk 102400 Apr 27 10:03 fs

$ /sbin/tune2fs -l fs
...
Block count:              100
...
Block size:               1024
Fragment size:            1024
Blocks per group:         8192
Fragments per group:      8192

所以文件系統塊大小是 1024,我們有 100 個文件系統塊(和 200 個 512 字節的設備塊)。拯救它:

$ ddrescue -b512 fs fs.new fs.log
GNU ddrescue 1.19
Press Ctrl-C to interrupt
rescued:    102400 B,  errsize:       0 B,  current rate:     102 kB/s
  ipos:     65536 B,   errors:       0,    average rate:     102 kB/s
  opos:     65536 B, run time:       1 s,  successful read:       0 s ago
Finished                                     

$ cat fs.log
# Rescue Logfile. Created by GNU ddrescue version 1.19
# Command line: ddrescue fs fs.new fs.log
# Start time:   2017-04-27 10:04:03
# Current time: 2017-04-27 10:04:03
# Finished
# current_pos  current_status
0x00010000     +
#      pos        size  status
0x00000000  0x00019000  +

$ printf "%i\n" 0x00019000
102400

所以十六進制ddrescue單位是字節,而不是任何塊。最後,讓我們看看有什麼debugfs用。首先,創建一個文件並找到它的內容:

$ sudo mount -o loop fs /mnt/tmp
$ sudo chmod go+rwx /mnt/tmp/
$ echo 'abcdefghijk' > /mnt/tmp/foo
$ sudo umount /mnt/tmp

$ hexdump -C fs
...
00005400  61 62 63 64 65 66 67 68  69 6a 6b 0a 00 00 00 00  |abcdefghijk.....|
00005410  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|

所以數據的字節地址是0x5400。將其轉換為 1024 字節的文件系統塊:

$ printf "%i\n" 0x5400
21504
$ expr 21504 / 1024
21

讓我們也嘗試一下塊範圍:

$ /sbin/debugfs fs
debugfs 1.43.3 (04-Sep-2016)
debugfs:  testb 0
testb: Invalid block number 0
debugfs:  testb 1
Block 1 marked in use
debugfs:  testb 99
Block 99 not in use
debugfs:  testb 100
Illegal block number passed to ext2fs_test_block_bitmap #100 for block bitmap for fs
Block 100 not in use
debugfs:  testb 21
Block 21 marked in use
debugfs:  icheck 21
Block   Inode number
21      12
debugfs:  ncheck 12
Inode   Pathname
12      //foo

這樣就可以按預期進行,除了塊 0 無效,可能是因為文件系統元數據在那裡。因此,對於您的字節地址0x30F8A71000ddrescue假設您在整個磁碟而不是分區上工作,我們減去分區開始的字節地址

210330128384 - 7815168 * 512 = 206328762368

將其除以tune2fs塊大小以獲得文件系統塊(請注意,由於多個物理的、可能已損壞的塊組成一個文件系統塊,因此數字不必是精確的倍數):

206328762368 / 4096 = 50373233.0

這就是你應該測試的塊debugfs

引用自:https://unix.stackexchange.com/questions/361421