dd conv=sync,noerror
(atau conv=noerror,sync
) merusak data Anda.
Bergantung pada kesalahan I / O yang dihadapi, dan pemblokiran yang digunakan (lebih besar dari ukuran sektor fisik?), Alamat input dan output tidak benar-benar tetap sinkron tetapi berakhir pada offset yang salah, yang membuat salinan tidak berguna untuk gambar sistem file dan lainnya hal-hal di mana offset penting.
Banyak tempat merekomendasikan penggunaan conv=noerror,sync
ketika berhadapan dengan disk yang buruk. Saya dulu membuat rekomendasi yang sama, sendiri. Itu berhasil bagi saya, ketika saya harus memulihkan disk buruk beberapa waktu lalu.
Namun, pengujian menunjukkan bahwa ini sebenarnya tidak dapat diandalkan sama sekali.
Gunakan losetup
dan dmsetup
untuk membuat A error B
perangkat:
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
Perangkat loop A, B terlihat seperti ini:
# head -n 3 $A $B
==> /dev/loop0 <==
A000000
A000001
A000002
==> /dev/loop1 <==
B000000
B000001
B000002
Jadi A, B dengan angka yang bertambah yang akan membantu kami memverifikasi offset nanti.
Sekarang untuk menempatkan kesalahan baca di antara keduanya, milik perangkat Linux mapper:
# dmsetup create AerrorB << EOF
0 2000 linear $A 0
2000 96 error
2096 2000 linear $B 48
EOF
Contoh ini dibuat AerrorB
seperti di 2000
sektor A
, diikuti oleh 2*48
sektor kesalahan, diikuti oleh 2000
sektor B
.
Hanya untuk memverifikasi:
# 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
Jadi terbaca sampai A127999\n
, karena setiap baris memiliki 8 byte yang totalnya 1024000 byte yang merupakan 2000 sektor kami dari 512 byte. Segalanya tampak teratur ...
Apakah akan berbaur?
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
Hasil:
# 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
Dari ukuran file saja Anda dapat mengatakan ada yang salah untuk beberapa pemblokiran.
Checksum:
# 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
setuju dengan ddrescue
hanya untuk ukuran blok yang kebetulan disejajarkan dengan zona kesalahan kami ( 512
, 4K
).
Mari kita periksa data mentah.
# 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
Walaupun data itu sendiri tampaknya ada, jelas tidak sinkron; offset benar-benar rusak untuk bs = 16K, 1M, 42,64K ... hanya yang dengan offset 2088576
yang benar, seperti yang dapat diverifikasi terhadap perangkat asli.
# dd bs=1 skip=2088576 count=8 if=/dev/mapper/AerrorB
B130000
Apakah ini perilaku yang diharapkan dd conv=noerror,sync
? Saya tidak tahu dan dua implementasi yang dd
saya miliki bahkan tidak setuju satu sama lain. Hasilnya sangat tidak berguna jika Anda digunakan dd
dengan pilihan blocksize pemain.
Di atas itu diproduksi menggunakan dd (coreutils) 8.25
, BusyBox v1.24.2
, GNU ddrescue 1.21
.