`Dd` veri bloklarını sağa kaydırmak için nasıl kullanılabilir?


10

Basit bir örnek olarak 100 MB'lık bir ham blok cihazı düşünün. Bu, her biri toplam 102760448 bayt için 512 baytlık 204800 bloktur.

Zor olan ilk 98MB'yi (200704 blok) kaydırmak, böylece önünde 2MB (4096 blok) boşluk var. Bunu yerinde yapmak için, henüz okunmamış bir sektöre hiçbir şey yazılmaması gerekir. Bunu başarmanın bir yolu bir tampon eklemektir:

$ dd if=/dev/sdj2 count=200704 | mbuffer -s 512 -b 4096 -P 100 | dd of=/dev/sdj2 seek=4096

Beklenti, mbufferyazara bir şey geçirmeden önce 4096 blok depolayacak, böylece okunmamış bir alana hiçbir şey yazılmamasını ve yazarın okuyucuyu arabellek boyutuna kadar geciktirmesini sağlayacaktır. Tampon, okuyucunun ve yazarın bu bileşenler içinde olabildiğince hızlı çalışmasına izin vermelidir.

Ancak, güvenilir bir şekilde çalışmıyor gibi görünüyor. Gerçek aygıtları kullanmayı denedim ama hiçbir zaman onlarla çalışmazken, bir dosya ile yapılan deneyler 64 bitlik kutumda çalıştı, ancak 32 bitlik kutumda çalışmadı.

İlk olarak, bazı hazırlık:

$ dd if=/dev/sdj2 count=200704 | md5sum
0f0727f6644dac7a6ec60ea98ffc6da9
$ dd if=/dev/sdj2 count=200704 of=testfile

Bu işe yaramıyor:

$ dd if=/dev/sdj2 count=200704 | mbuffer -s 512 -b 4096 -P 100 -H | dd of=/dev/sdj2 seek=4096
summary: 98.0 MiByte in  4.4sec - average of 22.0 MiB/s
md5 hash: 3cbf1ca59a250d19573285458e320ade

Bu, 64 bit sistemde çalışır, ancak 32 bit sistemde çalışmaz:

$ dd if=testfile count=200704 | mbuffer -s 512 -b 4096 -P 100 -H | dd of=testfile seek=4096 conv=notrunc
summary: 98.0 MiByte in  0.9sec - average of  111 MiB/s
md5 hash: 0f0727f6644dac7a6ec60ea98ffc6da9

Bu nasıl güvenilir bir şekilde yapılabilir?


notlar

Arabelleğe alma hakkında başka sorular okudum ve baktım pv, bufferve mbuffer. Ikincisi sadece gerekli arabellek boyutu ile çalışmak için alabilir.

Ara depolama kullanımı, her zaman çalışan soruna bariz bir çözümdür, ancak yeterli yedek kapasite olmadığında pratik değildir.

Arch Linux'u mbuffer20140302 sürümüyle çalıştıran test platformları .


Sorunu çözeceğini sanmıyorum, ama meraktan neden mbufferhiç kullanmıyorsunuz ? Bunun yerine neden ddblok cihazının tüm içeriğini tek seferde okuyorsunuz dd bs=102760448? Tabii ki, şu ya da bu şekilde RAM'de arabelleğe alınır.
Celada

@Celada - 100MB örneği sadece bir örnektir. Örneğin 1TB okumak bir seferde iyi bir fikir olmazdı.
starfry

2
Ah, şimdi anlıyorum, teşekkürler. mbufferAslında ikinci zorlamak gerektiğini ddilk için geride kalmaya ve sadece vardiya boyutunu tampon için yeterli RAM gerekir. Çok kötü dd, problemi ortadan kaldıracağından blokları geriye doğru sırada okumayı ve yazmayı desteklemez!
Celada

İkinci
md5sum'u

@psusi, ikinci md5 mbuffer tarafından verilir ( -Hargümanı bu özelliği etkinleştirir).
starfry

Yanıtlar:


2

Bir arabellek olmadan, her seferinde bir blok geriye doğru gidebilirsiniz.

for i in $(seq 100 -1 0)
do
    dd if=/dev/thing of=/dev/thing \
       bs=1M skip=$i seek=$(($i+2)) count=1
done

Lütfen bu örneğin hata kontrolünün olmaması nedeniyle tehlikeli olduğunu unutmayın.

Çağrı sayısı nedeniyle de yavaş dd. Yedeklenecek belleğiniz varsa, daha büyük bir blok boyutu kullanabilirsiniz.

Bir tampon ile tuzaklara dikkat edin . Öyle değil % 100 on doldurma garanti etmek için yeterli. İhtiyacınız olan şey, tüm süreç boyunca minimum bir dolum. Arabellek asla aşağıya düşmemelidir, 2Maksi takdirde henüz okunmamış verilerinizin üzerine yazmış olursunuz.

Teoride, herhangi bir tampon ve sadece zincir olmadan yapabilirsiniz dd:

dd if=/dev/thing bs=1M | \
dd bs=1M iflag=fullblock | \
dd bs=1M iflag=fullblock | \
dd of=/dev/thing bs=1M seek=2

Pratikte bu mu değil ilk garantisi yoktur çünkü güvenilir çalışması ddverileri okumaya devam yönetir son ederken, dd(ile 2Mzaten yazıyor aradaki "tampon" nin).

Tampon arasındaki girişi önemli ölçüde artırarak şansınızı önemli ölçüde artırabilirsiniz, ancak yine de güvenilir değildir.

Ne yazık ki minimum dolgu özelliği ile iyi bir tampon programı bilmiyorum. Arabellek içindeki güvenlik marjınızdan daha az olduğu sürece çıktıyı durdurana ihtiyacınız vardır.


Bunu kabul ettim çünkü orijinal soruyu nasıl ddkullanılabileceğini göstererek cevaplıyor . Bununla birlikte, gerçek çözümün kullanılması değil, ddbunun yerine geriye doğru çalışacak şekilde tasarlanmış bir şey seçtiğini düşünüyorum ddrescue. Bunu bir cevapta yapmanın bir yolunu anlattım.
starfry

1
@starfry: elbette, bunu yapan bir program güzel bir çözüm olacaktır. Ancak ddrescueburada hiç emin değilim . Farklı cihazlarda çalışmayı beklerse ve argümanlarınızı kabul etmek için kandırmanız gerekiyorsa değil. Dahili olarak "minimum arabellek dolgusu" özelliğine sahip olmayabilir (farklı cihazlarda gerekli olmadığından), bu nedenle verilerinizi bozabilir. Kaynak kodunu kullanım durumunuz için tasarlanmış olup olmadığını kontrol etmeniz gerekir.
frostschutz

1

4096 bloğu okuyorsunuz ve daha sonra bu 4096 bloğu diskin sonraki 4096 bloğuna yazıyorsunuz, böylece okunmadan önce ikinci 4096 bloğunun üzerine yazıyorsunuz. Yazmaya başlamadan önce bu ikinci 4096'yı almak için 8129 bloğu okumalısınız ve sonraki 4096'yı okumadan önce sadece 4096 blok yazmanız gerekir.

Bunun ne tür bir dosya sisteminden bahsetmedin. Ext [234] ise ve e2fsprogs'un son bir sürümüne sahipseniz kullanabilirsiniz e2image -ra -O 512 /dev/sdj2. Bu aynı zamanda birimdeki boş alanı atlayacak kadar akıllı olmanın da avantajına sahiptir.


Bunu okurken mantıklı ve ben de buna dayanarak bir kez daha bakacağım. Ancak test dosyasında neden çalıştığını açıklamıyor.
starfry

Dosya sistemi olarak, test dosyamı içeren dosya sistemine mi atıfta bulunuyorsunuz? Bu ext4ancak blok aygıt kopyası için, herhangi bir dosya sisteminin alakasız olması gerekir.
starfry

@starfry, bunu genel bir şekilde yapmayı bilmemin tek yolu, Emmanuel'in önerdiği (sondan geriye doğru çalışın) algoritmasını kullanmaktır.
psusi

blok boyutu yeniden, ben daha büyük bloklar denemişti (Ben soruda yazılı olmalıdır). 64K'lık bir sektör tamponunda bile daha güvenilir olmadığını gördüm. Güvenilir çözüm geriye gitmektir, ddbu da işe yaramaz.
starfry

1

Güvenilir bir çözüm, okunmamış bir alana hiçbir şey yazmadığından emin olmanızı gerektirir ve bunu gerçekleştirmenin tek gerçek yolu, kopyayı ters yönde yapmaktır.

ddrescueAracı ters yönde çalışabilir ama giriş ve çıkış aynı olan çalıştırmak reddeder. Ancak, aygıt düğümünü çoğaltarak kandırmak mümkündür.

Bazı hızlı deneyler yaptım ve işe yarıyor gibi görünüyor. Komut satırı:

$ ddrescue -f -R -s 200704s -o 4096s /dev/sdj11 /dev/sdj11_copy

Argümanlar

  • -f mevcut bir çıkış aygıtına yazmaya zorlamak için gereklidir
  • -R ters yönde çalışmasını söyler
  • -sgirdinin ne kadarının kopyalanacağını söyler s(sektör sayısını belirtmek için soneki kullandım )
  • -oyazmadan önce çıktı aygıtında ileriye doğru arama yapmasını söyler (sonekle birlikte tekrar sektörlerde belirtilir s)
  • /dev/sdj11 okunacak blok cihaz
  • /dev/sdj11_copy yazılacak blok cihaz

Oluşturduğum /dev/sdj11_copyile mknodparametrelerini maç için /dev/sdj11.

Ben sadece bazı çok hızlı testler yaptım ama bu ham bir cihaz kopyalamak için ok gibi görünüyor. Bir dosya üzerinde çalışmaz (aynı olan dosyaların ötesine geçmesini kandıramadım)

Bu, bunu nasıl başaracağımı sorduğum orijinal soruma cevap vermiyor, ddancak bence, diğer cevapları okuduktan sonra dd, bunun yapamaması.


ddrescueBu senaryoda kötü bir blok bulursa ne olur ? Diskin başka bir alanına atlarsa (bozuk blokları önlemek için) ve oradan kopyalamaya devam ederse, verilerinizin henüz kopyalanmayan kısımlarının üzerine tekrar yazacaktır. Aynı cihazla çalışmayı beklemiyorsa, çeşitli olası veri bozulması durumlarını önlemek için herhangi bir özel önlem almanın bir nedeni yoktur.
frostschutz

Bunun potansiyel bir sorun olduğunu kabul ediyorum, ancak ihtiyacım olanı yapmak için kullanabildiğim için son durumlara bakmadım. ddrescueKötü verileri kurtarma girişimlerini sınırlamak için seçenekler var, ancak bunları kullanmaya bakmadım.
starfry

Giriş ve çıkış aynı ise çalışmayı reddetmesi, güvenli olmadığının muhtemelen iyi bir göstergesidir.
psusi
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.