如何在測試檔案中模擬磁碟分割壞塊?

如何在測試檔案中模擬磁碟分割壞塊?

我想在實際應用之前測試一些磁碟救援方法,特別是 ddrescue 從多個磁碟副本恢復壞區塊的能力,假設每個副本中都有一個壞區塊沒有壞。

由於Linux下設備是用檔案來表示的,所以我認為可以在檔案中標記壞塊。假設我已經建立了一個參考文件和兩個副本,如下所示:

dd if=/dev/random of=/tmp/file bs=1024 count=32768
cp /tmp/file /tmp/file1
cp /tmp/file /tmp/file2

如何模擬 file1 和 file2 中的壞區塊,就好像它們是裝置檔案一樣?

解決方案這裡,這裡卡米爾·馬喬羅夫斯基和這裡是解決方案的好途徑,但沒有為我的用例提供完整的方法

答案1

感謝 Kamil Maciorowski 的建議和他在其他地方的回答,我可以建立以下流程並進行測試:

1)建立測試檔案並計算其哈希值以檢查未來的恢復情況

dd if=/dev/urandom of=/tmp/file bs=512 count=32768 status=progress
sha256sum /tmp/file
f90c19308f9f216bf7dece09dd849eb40e97cdef86c6c37f28fbaf9a7bd07503  /tmp/file

2)用它創建一個設備

loopdev=\`losetup -f --show /tmp/file\`
echo $loopdev
/dev/loop1

3)借助 devicemapper 創建帶有壞塊的損壞設備

dmsetup create file1 << EOF
    0  2048 linear $loopdev 0
 2048  4096 error
 6144  26624 linear $loopdev 6144
EOF

dmsetup create file2 << EOF
    0  30720 linear $loopdev 0
 30720  2048 error
EOF

ls -l /dev/mapper/
lrwxrwxrwx 1 root root       7 mai   30 09:27 file1 -> ../dm-2
lrwxrwxrwx 1 root root       7 mai   30 09:27 file2 -> ../dm-3

請注意,在每一行中,第一個數字是位置,第二個數字是大小,因此在最後一行中,總和是檔案的大小:6144 + 26624 = 32768,30720 + 2048 = 32768

該行6144 26624 linear $loopdev 6144的含義是:將裝置 $loopdev 從偏移量 6144(以位元組為單位)複製到偏移量 6144(以位元組為單位)處的 file1,大小為 26624 位元組。

4) 檢查預期位置的 I/O 錯誤

dd if=/dev/mapper/file1 of=/dev/null count=2048
ok
dd if=/dev/mapper/file1 of=/dev/null count=2049
dd: error reading '/dev/mapper/file1': Input/output error
dd if=/dev/mapper/file2 of=/dev/null count=30720
ok
dd if=/dev/mapper/file2 of=/dev/null count=30721
dd: error reading '/dev/mapper/file2': Input/output error

到了這個階段,OP的問題就得到了解答。讓我們進一步完成測試:

5) 測試 ddrescue : 僅好塊

ddrescue -B -v -n /dev/mapper/file1 /tmp/file1 /tmp/log
percent rescued:  87.50%
sha256sum /tmp/file1
0d344253f69688e23dd4558c2ffdabb0325f85848f7e65788ea5c9441e7a700c  /tmp/file1

6)用第二個副本成功修復壞塊

ddrescue -B -v -c 16 -r 2 /dev/mapper/file2 /tmp/file1 /tmp/log
percent rescued: 100.00%
sha256sum /tmp/file1
f90c19308f9f216bf7dece09dd849eb40e97cdef86c6c37f28fbaf9a7bd07503  /tmp/file1

7) 如果需要(不是100%),嘗試用第一個副本來挽救壞塊

ddrescue -B -v -c 16 -r 2 /dev/mapper/file1 /tmp/file1 /tmp/log

8)清理

dmsetup remove file1
dmsetup remove file2
unset loopdev
rm /tmp/file* /tmp/log

相關內容