dd conv=sync,noerror
(veya conv=noerror,sync
) verilerinizi bozar.
Karşılaşılan G / Ç hatasına ve kullanılan blok boyutuna (fiziksel sektör boyutundan daha büyük?) Bağlı olarak, giriş ve çıkış adresleri aslında senkronize değil, yanlış ofsetlerle sonuçlanır, bu da kopyayı dosya sistemi görüntüleri ve diğerler için işe yaramaz hale getirir. ofsetlerin önemli olduğu şeyler.
conv=noerror,sync
Kötü disklerle uğraşırken birçok yer kullanmanızı öneririz . Aynı öneriyi kendim yapardım. Bir süre önce kötü bir diski kurtarmak zorunda kaldığımda benim için işe yaradı.
Bununla birlikte, testler bunun aslında hiçbir şekilde güvenilir olmadığını göstermektedir.
Bir cihaz oluşturmak için losetup
ve dmsetup
öğelerini kullanın A error 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
A, B döngü cihazları şöyle görünür:
# head -n 3 $A $B
==> /dev/loop0 <==
A000000
A000001
A000002
==> /dev/loop1 <==
B000000
B000001
B000002
Bu nedenle, daha sonra ofsetleri doğrulamamıza yardımcı olacak artan rakamlarla A, B'dir.
Şimdi, ikisi arasında bir Linux aygıtı eşleştiricisi nezaketine okuma hatası koymak:
# dmsetup create AerrorB << EOF
0 2000 linear $A 0
2000 96 error
2096 2000 linear $B 48
EOF
Bu örnek oluşturur AerrorB
gibi 2000
sektörler A
, ardından 2*48
hata sektörler, ardından 2000
sektörler B
.
Sadece doğrulamak için:
# 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
Böylece A127999\n
, her satırın 2000 baytı 512 bayt olan 1024000 bayt olan toplam 8 bayta ulaştığını görüyoruz. Her şey yolunda görünüyor.
Karışacak mı?
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
Sonuçlar:
# 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
Yalnızca dosya boyutlarından bazı blok boyutları için bazı şeylerin yanlış olduğunu söyleyebilirsiniz.
checksum'ları:
# 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
ddrescue
sadece bizim hata bölgemize hizalanacak blok boyutları için kabul eder ( 512
, 4K
).
Ham verileri kontrol edelim.
# 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
Verilerin kendisi mevcut gibi gözükse de, açıkçası senkronize değil; ofsetler bs = 16K, 1M, 42,64K ... için tamamen kapalı durumdadır ... sadece ofsetli olanlar 2088576
orijinal cihaza göre doğrulanabilir.
# dd bs=1 skip=2088576 count=8 if=/dev/mapper/AerrorB
B130000
Bu beklenen davranış dd conv=noerror,sync
mı? Bilmiyorum ve elimdeki iki uygulama dd
birbiriyle aynı fikirde bile değil. dd
Performansı bloksuz bir seçim ile kullandıysanız sonuç çok işe yaramaz .
Yukarıda kullanılarak üretilmiştir dd (coreutils) 8.25
, BusyBox v1.24.2
, GNU ddrescue 1.21
.