dd conv=sync,noerror
(hoặc conv=noerror,sync
) làm hỏng dữ liệu của bạn.
Tùy thuộc vào lỗi I / O gặp phải và kích thước khối được sử dụng (lớn hơn kích thước khu vực vật lý?), Các địa chỉ đầu vào và đầu ra không thực sự đồng bộ mà kết thúc ở phần bù sai, khiến bản sao trở nên vô dụng đối với hình ảnh hệ thống tập tin và các hình ảnh khác những điều bù đắp quan trọng.
Rất nhiều nơi khuyên bạn nên sử dụng conv=noerror,sync
khi xử lý các đĩa xấu. Tôi đã từng đưa ra khuyến nghị tương tự, bản thân mình. Nó đã làm việc cho tôi, khi tôi phải khôi phục một đĩa xấu một thời gian trước đây.
Tuy nhiên, thử nghiệm cho thấy rằng điều này thực sự không đáng tin cậy theo bất kỳ cách nào.
Sử dụng losetup
và dmsetup
để tạo một A error B
thiết bị:
truncate -s 1M a.img b.img
A=$(losetup --find --show a.img)
B=$(losetup --find --show b.img)
i=0 ; while printf "A%06d\n" $i ; do i=$((i+1)) ; done > $A
i=0 ; while printf "B%06d\n" $i ; do i=$((i+1)) ; done > $B
Các thiết bị lặp A, B trông như thế này:
# head -n 3 $A $B
==> /dev/loop0 <==
A000000
A000001
A000002
==> /dev/loop1 <==
B000000
B000001
B000002
Vì vậy, đó là A, B với các số tăng dần sẽ giúp chúng tôi xác minh các lần bù sau.
Bây giờ để đặt một lỗi đọc ở giữa hai, nhờ phép của trình ánh xạ thiết bị Linux:
# dmsetup create AerrorB << EOF
0 2000 linear $A 0
2000 96 error
2096 2000 linear $B 48
EOF
Ví dụ này tạo ra AerrorB
như trong các 2000
lĩnh vực của A
, theo sau là các 2*48
lĩnh vực lỗi, tiếp theo là các 2000
lĩnh vực của B
.
Chỉ cần xác minh:
# blockdev --getsz /dev/mapper/AerrorB
4096
# hexdump -C /dev/mapper/AerrorB
00000000 41 30 30 30 30 30 30 0a 41 30 30 30 30 30 31 0a |A000000.A000001.|
00000010 41 30 30 30 30 30 32 0a 41 30 30 30 30 30 33 0a |A000002.A000003.|
[...]
000f9fe0 41 31 32 37 39 39 36 0a 41 31 32 37 39 39 37 0a |A127996.A127997.|
000f9ff0 41 31 32 37 39 39 38 0a 41 31 32 37 39 39 39 0a |A127998.A127999.|
000fa000
hexdump: /dev/mapper/AerrorB: Input/output error
Vì vậy, nó đọc cho đến A127999\n
khi mỗi dòng có 8 byte tổng cộng ở mức 1024000 byte, đó là 2000 lĩnh vực 512 byte của chúng tôi. Mọi thứ dường như được sắp xếp theo thứ tự ...
Nó sẽ được pha trộn?
for bs in 1M 64K 16K 4K 512 42
do
dd bs=$bs conv=noerror,sync if=/dev/mapper/AerrorB of=AerrorB.$bs.gnu-dd
busybox dd bs=$bs conv=noerror,sync if=/dev/mapper/AerrorB of=AerrorB.$bs.bb-dd
done
ddrescue /dev/mapper/AerrorB AerrorB.ddrescue
Các kết quả:
# ls -l
-rw-r--r-- 1 root root 2113536 May 11 23:54 AerrorB.16K.bb-dd
-rw-r--r-- 1 root root 2064384 May 11 23:54 AerrorB.16K.gnu-dd
-rw-r--r-- 1 root root 3145728 May 11 23:54 AerrorB.1M.bb-dd
-rw-r--r-- 1 root root 2097152 May 11 23:54 AerrorB.1M.gnu-dd
-rw-r--r-- 1 root root 2097186 May 11 23:54 AerrorB.42.bb-dd
-rw-r--r-- 1 root root 2048004 May 11 23:54 AerrorB.42.gnu-dd
-rw-r--r-- 1 root root 2097152 May 11 23:54 AerrorB.4K.bb-dd
-rw-r--r-- 1 root root 2097152 May 11 23:54 AerrorB.4K.gnu-dd
-rw-r--r-- 1 root root 2097152 May 11 23:54 AerrorB.512.bb-dd
-rw-r--r-- 1 root root 2097152 May 11 23:54 AerrorB.512.gnu-dd
-rw-r--r-- 1 root root 2162688 May 11 23:54 AerrorB.64K.bb-dd
-rw-r--r-- 1 root root 2097152 May 11 23:54 AerrorB.64K.gnu-dd
-rw-r--r-- 1 root root 2097152 May 11 23:54 AerrorB.ddrescue
Từ kích thước tập tin một mình, bạn có thể nói những điều sai đối với một số khối.
Tổng kiểm tra:
# md5sum *
8972776e4bd29eb5a55aa4d1eb3b8a43 AerrorB.16K.bb-dd
4ee0b656ff9be862a7e96d37a2ebdeb0 AerrorB.16K.gnu-dd
7874ef3fe3426436f19ffa0635a53f63 AerrorB.1M.bb-dd
6f60e9d5ec06eb7721dbfddaaa625473 AerrorB.1M.gnu-dd
94abec9a526553c5aa063b0c917d8e8f AerrorB.42.bb-dd
1413c824cd090cba5c33b2d7de330339 AerrorB.42.gnu-dd
b381efd87f17354cfb121dae49e3487a AerrorB.4K.bb-dd
b381efd87f17354cfb121dae49e3487a AerrorB.4K.gnu-dd
b381efd87f17354cfb121dae49e3487a AerrorB.512.bb-dd
b381efd87f17354cfb121dae49e3487a AerrorB.512.gnu-dd
3c101af5623fe8c6f3d764631582a18e AerrorB.64K.bb-dd
6f60e9d5ec06eb7721dbfddaaa625473 AerrorB.64K.gnu-dd
b381efd87f17354cfb121dae49e3487a AerrorB.ddrescue
dd
chỉ đồng ý với ddrescue
các kích thước khối xảy ra được căn chỉnh theo vùng lỗi của chúng tôi ( 512
, 4K
).
Hãy kiểm tra dữ liệu thô.
# grep -a -b --only-matching B130000 *
AerrorB.16K.bb-dd: 2096768:B130000
AerrorB.16K.gnu-dd: 2047616:B130000
AerrorB.1M.bb-dd: 2113152:B130000
AerrorB.1M.gnu-dd: 2064000:B130000
AerrorB.42.bb-dd: 2088578:B130000
AerrorB.42.gnu-dd: 2039426:B130000
AerrorB.4K.bb-dd: 2088576:B130000
AerrorB.4K.gnu-dd: 2088576:B130000
AerrorB.512.bb-dd: 2088576:B130000
AerrorB.512.gnu-dd: 2088576:B130000
AerrorB.64K.bb-dd: 2113152:B130000
AerrorB.64K.gnu-dd: 2064000:B130000
AerrorB.ddrescue: 2088576:B130000
Mặc dù dữ liệu dường như có mặt, nhưng rõ ràng nó không đồng bộ; các độ lệch hoàn toàn vượt quá giới hạn cho bs = 16K, 1M, 42,64K ... chỉ những điểm có bù 2088576
là chính xác, như có thể được xác minh đối với thiết bị gốc.
# dd bs=1 skip=2088576 count=8 if=/dev/mapper/AerrorB
B130000
Đây có phải là hành vi dự kiến của dd conv=noerror,sync
? Tôi không biết và hai triển khai của dd
tôi đã có sẵn thậm chí không đồng ý với nhau. Kết quả là rất vô dụng nếu bạn sử dụng dd
với lựa chọn kích thước biểu diễn.
Trên đây được sản xuất sử dụng dd (coreutils) 8.25
, BusyBox v1.24.2
, GNU ddrescue 1.21
.