Tek bir parçayı bir dosyada nasıl çevirebilirim?


35

Btrfs 'in kendi kendini iyileştirebileceği iddialarını test etmek için kasıtlı olarak bir dosyaya zarar vermek istiyorum . Makale, dosya sistemini kaldırmak, bir tek bir parçayı çevirmek ve ardından yeniden yerleştirmek suretiyle bir fotoğrafa zarar vermek hakkında konuşuyor. Eski dosya sistemlerinde bu sadece bozulur, ancak kendisini btrfs ile düzeltmesi gerekir. Teorik olarak, bu mantıklı ama ben gerçekten test etmek istiyorum.

Sorun, makalenin bunlardan herhangi birinin nasıl yapılacağını açıklamamasıdır .
Bir dosya sisteminin çok özel bir kısmındaki tek bir bitin değiştirilmesi konusunda nasıl gidebilirim?

Bunun çevrimdışı bir dosya sisteminde yapılması gerektiğini de belirtmeliyim ki btrfs yazımı kasıtlı olarak görmüyor.

Düzenleme: Soru (ve tartışma) btrfs hakkında çok konuşur, bu yolsuzluğun uygulanmasında dosya sistemi ile ilgili bağımsız yöntemler olup olmadığını bilmek isterim (böylece farklı RAID türleri / denetleyicileri / vb. İle karşılaştırılabilir).


@Dan, eğer dosyayı doğrudan düzenlersem, btrfs (veya bu konuda herhangi bir dosya sistemi) geçerli bir yazı olarak sayılır. Aradığım yolsuzluğu vermezdi.
Oli

Bu bir test dosya sistemi midir? Yani, içeriği umursamıyor musunuz veya yedeklemeden geri yükleme yapmak için tamamen iyi misiniz? Ayrıca, tek bir sürücüde tek bir btrfs bölümü veya RAID dizisinin tepesinde tek bir bölüm kullanıyor musunuz? - veya başka bir yapılandırma?
Darth Android

1
Btrfs doğru ioctls'leri destekliyorsa (eğer emin değil), filefrag -vbir dosyanın tam olarak nerede olduğunu bulmak için kullanabilirsiniz .
derobert

3
@Oli, hem oylar hem de cevaplar açısından U&L'de daha fazla ilgi duyan bir kitle bulacağınızdan şüpheleniyorum. artı, bu .
strugee

1
Sadece doğru noktada kozmik bir ışın çekin.
smcg

Yanıtlar:


20

Ben uzman değilim, ama btrfs-progspakette aslında bunu yapmak için özel bir araç var, ancak kaynaktan bir kaynak yapmanız gerekebilir. Her durumda, kurduktan veya oluşturduktan sonra, btrfs geliştiricileri tarafından dosya sistemini test etmek için kullanılan btrfs-progsaracı kullanabilmelisiniz btrfs-corrupt-block.

Şimdi dediğim gibi, btrfs ile oynayacak çok fazla zamanım olmadı, bu yüzden bu aracın tam olarak kullanıldığını bilmiyorum. Ancak bununla, bozuk bir dosya okunduğunda sabitlenecek çevrimdışı bir dosya sistemini bozabilmelisiniz (RAID veya başka bir kopya kullanmak için bir şey ayarladığınızı varsayarak).


2
Müthiş Bul! Bunun btrfs-corrupt-blockbtrfs geliştiricileri tarafından gerçek bir sınav olduğu ve bir "numara" olarak yazılmadığı varsayılırsa , bunun tasarıya tam olarak uyması gerekir.
allquixotic

@allquixotic Eğer btrfs hakkında daha fazla bilgi edinmek istiyorsanız , linux.conf.au 2012'den harika bir konuşma var . Dediğim gibi btrfs-corrupt-block, geliştiriciler tarafından kullanılır, bu yüzden bir hile olsaydı çok yararlı olmazdı :)
strugee

3
@ allquixotic Açık kaynağın güzelliği: btrfs kaynak koduna bakabilir ve kontrol edebilirsiniz! Tabii, bu kolay bir iş olmaz, ama gerçekten istiyorsan, bunu yapabilirsin .
Bakuriu,

@Bakuriu Ben tamamen bunun farkındayım. Asla btrfs-corrupt-blockbir test olmadığından asla ciddiye almadım , çünkü kaynağında birileri tarafından çok hızlı bir şekilde keşfedilir ve Oracle'a karşı negatif PR olarak kullanılır (en azından; diğer btrfs geliştiricileri / katkıda bulunanları). Bu sadece manşetsiz bir yorumdu.
allquixotic

OP (@Oli) 'nin bir bloğu (yani, dosya sistemi yapısını) veya bir dosyayı (yani, bir dosyanın içeriğini bozmak mı istiyor?) İstemesini merak ediyorum ... Ve btrfs'in kendi kendini iyileştirme iddiasıyla ilgili olduğuna inanıyorum. eski değil mi? [Bir dosya sistemi hangi bitin bir dosyaya çevrildiğini nasıl bilebilir? bir çeşit CRC?]. Bu cevap muhtemelen sağda, yani +1. [ama "tek bir bit" ten daha fazla değişebilir mi? ya da "her yerde" gerçekleşen rastgele bir bitten daha kolay iyileşebilecek bir şeyi mi değiştirelim?]
Olivier Dulac

16
  1. Tek bir sektörün değerini blok cihazda (örneğin /dev/sda1) 1 milyon sektör ofsetle (sadece bir örnek) elde edin:

    sudo dd if=/dev/sda1 of=/root/mysector bs=512 count=1 skip=1M
    

    Bu rasgele seçilen 1M * 512 bayt ofset, yalnızca dosya sisteminin meta veri bölümünden ve aslında veri içeren bir sektörde olduğundan emin olmak içindir.

  2. Bir hex editörüyle içeriği değiştirerek ham sektör verilerini düzenleyin. Örneğin , Linux için iyi bir hex editörüne ihtiyacınız var .

  3. Sektörü ard arda ifve ofargümanları ters çevrilmiş olarak geri koyun :

    sudo dd if=/root/mysector of=/dev/sda1 bs=512 count=1 seek=1M
    

2
Bu, 1 milyonuncu blok aslında bir dosyanın parçası olmadığı sürece test yapmasına yardımcı olmaz. Belirli bir dosyanın hangi bloğunda başladığını nasıl anlayabilir?
Darth Android

3
Budur böylece neredeyse orada. Dd komutunu dosyanın tam konumuna kilitleyebilirseniz, bu duruma yaklaşmanın en iyi yolu bu olabilir.
Oli

@Oli Evet, dosya sistemlerinin Ext ailesi için nasıl yapılacağını biliyorum, ancak btrfs ile bu kadar fazla deneyimim yok. Bir yol bulabilir miyim bakayım.
gertvdijk

2
@Oli: basitçe bir döngüye sahip olabilirsiniz, bloğun dışına taşan bir blok (örneğin yukarıdaki gibi, ancak "atla = N", N 1..max'tadır), düzenlemek istediğiniz dosyadan bir satır çizene kadar [başka hiçbir yerde olmayacak bir çizgi oluşturmaya çalışın ... örneğin bir şifre üreticisinden alın ve yeterince uzun mu?]. Sonra o belirli bloğu düzenlersiniz. remount, testin değiştirilip değiştirilmediğini test et (şüpheliyim, en üstteki cevabımdaki yorumuma bakın ... dosya verileri (= içerik) ile dosya sistemi yapısının kendisi arasında bir karışıklık var gibi görünüyor (= dosyalar ve içeriklerinin nasıl organize edildiği )?)
Olivier Dulac

16

@Oli - merhaba, ben Jim Salter, bu yazıyı gerçekten yazan adam. Sanal makine ile çalışıyordum, bu da işleri kolaylaştırdı. Yaptığım JPEG dosyasıyla başladı ve hex editöründe açtı. Kullandığım belirli bir tanesi Ubuntu'da basit bir apt-get install bless korusun ile kurabileceğiniz Bless .

JPEG'i Bless'da açtıktan sonra, JPEG'in "et" ’ini elde etmek için birkaç kez sayfayı aşağıya vurdum ve sonra yaklaşık elli baytlık veriyi vurguladım ve kopyalayıp bir metin editörüne yapıştırdım ( durumda, gEdit). Bu bana aranacak bir şey verdi.

Şimdi JPEG'i VM'deki her diziye kaydettim. Dizilerin arkasındaki depolama, bir dizi .qcow2 dosyasıydı. JPEG'i dizilere kaydettikten sonra, her bir diziyle ilişkili .qcow2 dosyalarını Bless'a yükleyebilir ve onları arayabilirdim - çok büyük değildiler, JPEG ve bazı meta verilerden başka bir şey olmadılar - bu elli baytlık model için Vurguladım ve JPEG'den kopyaladım. Voila, yolsuzluk yapmam gereken bir engel vardı! Bu noktada, JPEG'in sanal baytında saklanan JPEG tek tek baytlarını Bless kullanarak el ile düzenleyebiliyordum - ve en önemlisi bunu her bir dizide aynı şekilde yapıyordum .

Tek kırışıklık, makalede test edilen RAID5 dizisinin söz konusu olması durumunda, şeritteki verilerin asıl kopyasını düzenlediğimden emin olmam gerekiyordu, şerit için eşlik değil - bu küçük bir görüntü. aksi halde boş dizi, bu nedenle şeritteki FOLLOWING bloğunda herhangi bir veri olmadığından parite bloğunun veri bloğundan değiştirilmemiş verileri içermesini sağlayın. Yanlışlıkla veri bloğu yerine eşlik bloğunu düzenleseydim, resim değişmemiş olarak görünürdü.

Son bir not - bunu yapmak için sanal makinelere ihtiyaç duymazsınız - aynı şeyleri aynı şekilde çıplak metalle yapabilirsiniz; sadece küçük bir .qcow2 dosyası yerine tüm ham sürücülerle çalışmanız gerekeceği için sürücüleri kullanmanız gerekebilir, ya da sürücüleri çekmeniz ve farklı bir makineye koymanız gerekebilir ya da önyükleme yapmak için canlı (veya yalnızca alternatif) bir ortama önyükleme yapın. (ZFS'nin veri iyileştirmesini tam olarak bu şekilde test ettim, ancak 7 yıl önce yeni nesil dosya sistemlerine ilgi duyduğumda gerçek metal makinelerde.

Bu yardımcı olur umarım!


4

Açılan dosya üzerinde çalışacak küçük bir programı deneyebilirsiniz .FIBMAP ioctl(2)

Hızlı web arama ile bu blog yazıyı buldum http://smackerelofopinion.blogspot.tw/2009/06/fibmap-ioctl-file-system-block-number.html bunun nasıl yapılacağını gösteren - hatta size bir link verecek Derleyebileceğiniz ve çalıştırabileceğiniz örnek bir program.

$ git clone git://kernel.ubuntu.com/cking/debug-code
$ cd debug-code/block-mapper-fibmap
$ make
$ sudo ./fibmap /path/to/your/image-file.jpg

Bu tam olarak hdparm --fibmap(@ falconer tarafından belirtilen) uygulanan yoldur .

Blok numaralarını bulduktan sonra dd, dosyayı değiştirmek için gertfu kullanabilir, @gertvdijk çizilir. Veya belki de sadece fibmap.cyukarıda belirtilen programı, sizin için bit çevirmek üzere, dosya sistemi katmanını (program için üç parametre: 1. dosyanın yolunu, 2. dosyayı içeren dosya yolunu yazarak, doğrudan aygıt dosyasına yazarak) değiştirebilirsiniz. sistemi, 3. ofset ve değiştirmek istediğiniz bit).

( Feragatname: Test etmedim ve FIBMAP ioctl(2)bir geridöngü aygıtında veya btrfs dosya sisteminde bir dosya için çalışacağını garanti edemedim, ancak kesinlikle olmasını beklerdim. Dosyayı gerçekleştirmeden önce aygıt türünü kontrol edeceğini tahmin ediyorum ve bu nedenle başarısız).hdparmioctl(2)


3
sudo hdparm --fibmap /PATH/TO/FILE

Dosyanın bulunduğu LBA'ları size verecek. Bundan sonra @gertvdijk'in cevabını kullanabilirsiniz.


Ne yazık ki bu işe yaramadı. Tükürüyor Bir 0,39: device not found in /devya btrfs ya da (daha büyük olasılıkla) çünkü geridönüşümlü dosyalar üzerinde kullanıyorum. Bunu "uygun" bir VM ile yapmayı deneyeceğim.
Oli

@Oli Hmm. hdparmHer dosya sisteminde işe yaradığını düşündüm ama belki de öyle değil.
Şahin
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.