Bir Linux disk görüntüsünü seyrek bir dosyaya nasıl dönüştürebilirim?


12

Bir EXT bölümünde ddrescue ile yapılmış bir sürü disk görüntüsü var ve hala monte edilebilirken veri kaybetmeden boyutlarını küçültmek istiyorum.

Görüntünün dosya sistemindeki boş alanı sıfırlarla nasıl doldurabilirim ve sonra bu boş alanın gerçekten diskte depolanmaması için dosyayı seyrek bir dosyaya nasıl dönüştürebilirim ?

Örneğin:

> du -s --si --apparent-size Jimage.image 
120G Jimage.image
> du -s --si Jimage.image 
121G Jimage.image

Bu aslında üzerinde sadece 50G gerçek veri var, bu yüzden ikinci ölçüm çok daha küçük olmalı.

Bu sözde boş alanı sıfırlarla dolduracaktır:

cat /dev/zero > zero.file
rm zero.file

Ancak seyrek dosyalar şeffaf bir şekilde işlenirse, sanal diske hiçbir şey yazmadan aslında seyrek bir dosya oluşturabilir, bu da ironik bir şekilde sanal disk görüntüsünü seyrek bir dosyaya dönüştürmemi engelleyebilir. :) Yapar?

Not: Bazı nedenlerden dolayı, takılı bir disk görüntüsünde çalışmadığında sudo dd if=/dev/zero of=./zero.fileçalışır cat.


2
Bir dosyaya sıfır yazmak, seyrek bir dosya oluşturmaz. Bu farklı bir kavram. İşletim sistemi veri bloğunun gerçekten orada olmadığını keşfettiğinde (engelleme listesi o bölgedeki veriler için boştur) seyrek bir dosya ararken / okurken, (OS) otomatik olarak okuma arabelleğini sıfır bayt ile doldurur.
hotei

Not: komutunuz sudo cat /dev/zero > zero.fileyürütülmeden önce bash (sizin gibi çalışıyor, kök değil) yeniden yönlendirme yaptığı için çalışmaz sudo. Bkz. Unix.stackexchange.com/questions/1416/…
Fritz

Yanıtlar:


19

Her şeyden önce, seyrek dosyalar yalnızca arama yaparsanız, sıfır yazarsanız değil, yalnızca şeffaf bir şekilde işlenir.

Daha açık bir şekilde ifade etmek gerekirse, Wikipedia'dan örnek

dd if=/dev/zero of=sparse-file bs=1k count=0 seek=5120

yok değil herhangi sıfır yazmak, aramak (üzerinden atlamak), 5MB çıktı dosyasını açın ve sonra yazacak sıfır (hiç yani hiçbir şey) sıfır. Bu komut ( Wikipedia'dan değil )

dd if=/dev/zero of=sparse-file bs=1k count=5120

5MB sıfır yazacak ve seyrek bir dosya oluşturmayacak!

Sonuç olarak, zaten seyrek olmayan bir dosya daha sonra sihirli bir şekilde seyrek olmayacaktır.

İkincisi, seyrek sıfır dolu bir dosyayı yapmak, yapmak zorundasın cp o

cp --sparse=always original sparsefile

veya tar veya rsync'in --sparse seçeneğini de kullanabilirsiniz.


1
Wikipedia'ya göre, dd ile sıfırlar yazmak seyrek bir dosya oluşturacaktır. "Aramanın" ne anlama geldiğini açıklayabilir misiniz?
endolith

1
Peki ya kedi? Adam sayfasında seyrek dosyalar hakkında hiçbir şey yok, bu yüzden cat /dev/zero > zero.fileboş alanı sıfırlarla doldurmak için mükemmel bir şey olduğunu varsayıyorum ?
Ludwig Weinzierl

2
@ endolith: Sıfır ddyazmak veya aramak için farkın ne olduğunu netleştirmek için cevabım güncellendi .
mihi

2
@Ludwig Weinzierl: Evet, bu catkomut tüm diskinizi (veya en azından kök veya kota için ayrılmış olmayan miktarı) "gerçek" sıfırlarla dolduracak ve seyrek dosyalar oluşturmayacaktır.
mihi

1
@endolith ekstra alana ihtiyacınız olacak, evet. ancak tarball'ı sıkıştırabildiğiniz için, yalnızca orijinal dosya ve seyrek dosyanın sıkıştırılmış bir sürümü için alana ihtiyacınız olacaktır.
mihi

12

Belki de bir dosyayı yerinde düzenlemenin en kolay yolu fallocateyardımcı programı aşağıdaki gibi kullanmaktır :

fallocate -v --dig-holes {file_name}

fallocate (1) , Debian üzerindeki util-linux paketi tarafından sağlanmaktadır .


1
Herhangi bir nedenle, fallocate --dig-holes299GiB orijinalinden 103GiB dosyasıyla sonuçlanırken cp --sparse=always, bana 93GiB verdi - hepsi aynı SHA1 toplamıyla (boyutları du -B1Gvs ile kontrol edildi du --apparent-size -B1G). Yani fallocatedaha düşük sonuçlar veriyor gibi görünüyor.
Ruslan

3

Cevabımı bütünlük için düzenleme:

  1. Sıfırla balon boş FS alanı (UYARI: disk görüntünüzü değiştirir):

losetup --partscan --find --show disk.img

Disk olarak / dev / loop1 verdiğini ve yalnızca bir bölüm olduğunu varsayalım, aksi takdirde içinde monte edilebilir FS bulunan her bölüm için bunu tekrarlamamız gerekir (takas bölümünü yok sayın vb.).

mkdir -p /mnt/tmp mount /dev/loop1p1 /mnt/tmp dd if=/dev/zero of=/mnt/tmp/tempfile

ENOSPC ile başarısızlığa uğramasına izin verin.

/bin/rm -f /mnt/tmp/tempfile umount /mnt/tmp losetup -d /dev/loop1

  1. Seyrek bir resme kopyalama:

'dd', sıfırlı bir dosyayı seyrek bir dosyaya dönüştürme seçeneğine sahiptir:

dd if=disk.img of=disk-sparse.img conv=sparse



1
Evet, bu seçenek OP'nin sorulduğu andan itibaren değildir. Bu daha fazla "diğer arayanlar için bir ekmek kırıntı bırakın" ... :-)
Lam Das

1
dosya sistemi türüne bağlı olarak, dosya sistemine zerofreesıfır yüklemek ve yazmaktan daha hızlı olabilir ve zaten çok fazla sıfır içeriyorsa disk görüntüsünün daha az büyümesini sağlar.
mihi

2

Ddrescue tarafından oluşturulan görüntünüzün 50 GB olduğunu ve gerçekte daha az bir şeyin yeterli olacağını mı kastediyorsunuz?

Bu durumda, önce dd ile yeni bir resim oluşturamazdınız:

dd if=/dev/zero of=some_image.img bs=1M count=20000

ve içinde bir dosya sistemi oluşturun:

mkfsofyourchoice some_image.img

sonra sadece görüntüyü monte ve eski görüntüden yenisine her şeyi kopyalamak? Bu senin işine yarar mıydı?


2

PartImage sadece bir dosya sisteminin kullanılmış bloklarını saklayan disk görüntüleri oluşturabilir, böylece kullanılmayan bloğu göz ardı ederek gerekli alanı büyük ölçüde azaltır. Ortaya çıkan görüntüleri doğrudan monte edebileceğinizi düşünmüyorum, ancak gidiyorsunuz:

image -> partimage -> image -> cp --sparse=alway

İstediğinizi üretmelisiniz (son adımı atmak bile mümkün olabilir, denemedim).


1
Ne yazık ki, bölümleme tarafından oluşturulan görüntüler tekrar genişletilmeden monte edilemez, bu da onları sadece arşivleme amaçları için uygun hale getirir.
Perkins

0

Şimdi bunu yapacak virt-sparsify adlı bir araç var . Boş alanı sıfırlarla doldurur ve ardından görüntüyü seyrek bir dosyaya kopyalar. Yine de çok fazla bağımlılık yüklemeyi gerektirir.


-2

GERÇEKTEN yapmak istediğiniz şey buysa, bu spesifikasyona yazılan özel bir programa ihtiyacınız olacağını sanıyorum. Ama bu ...?

Aslında çok sayıda sıfır alanınız varsa, iyi bir sıkıştırma aracı önemli ölçüde düşecektir. Ve seyrek dosyalar yazmaya çalışmak her durumda işe yaramaz. Doğru hatırlıyorsam, seyrek dosyalar bile en az 1 blok çıkış depolama alanı kaplar, burada giriş bloğu sıfır olmayan HERHANGİ bir bit içerir. Örneğin, 512 baytlık blok başına ortalama 1 sıfır olmayan bite sahip bir dosyanız olduğunu varsayalım - "seyrek" olarak yazılamaz. Bu arada, dosyayı zip, bzip, bzip2 veya p7zip ile sıkıştırırsanız veri kaybetmezsiniz. Kayıp olan mpeg veya jpeg sıkıştırması gibi değiller.

Öte yandan, dosyaya rastgele arama okumaları yapmanız gerekiyorsa, sıkıştırma değerinden daha fazla sorun olabilir ve seyrek yazmaya geri dönersiniz. Yetkili bir C veya C ++ programcısı böyle bir şeyi bir saat veya daha kısa sürede yazabilmelidir.


İlginç - bir aşağı oy henüz yazdıklarımın hiçbir çürümesi olmadığını fark ettim. Eğer doğruysa ama yararsızsa bu aşağıya inmek için bir neden değildir. Doğru ve yararlı değilse, o zaman hak ediyor.
hotei

Başka bir yerde OP'nin sıkıştırılmış görüntüleri monte etmekle ilgili bir sorusu olduğunu görüyorum. Bunun iş parçacığının devamı olduğunu varsayıyorum. Artık sıkıştırma önerimin neden kabul edilmediğini anlayabiliyorum. Basit bir C programı, seyrek dosyalar oluşturmanın kolay bir yoludur. AMA - (belirtilmemiş) işletim sistemi seyrek bir ISO takmanıza izin verir mi? Ubuntu ISO mounter kadar seçiciyim,% 100 emin değilim ...
hotei

4
Neden tekerleği yeniden icat ettiniz? cp --sparse=alwaysiyi çalışıyor
mihi

@mihi: Bu iyi bir fikir. BSD lezzetlerinde ( freebsd.org/cgi/… ) bulunmadığı için seyrek seçeneği bilmiyordum ve cp için bir Linux man sayfasına (bugüne kadar) bakma gereği duymadım.
hotei

Sıkıştırılmış görüntülerinize sahip olmanın ve bunları monte etmenin bir yolu, bunları yerel sıkıştırmayı destekleyen bir dosya sisteminde depolamaktır. Bir sürücü çökmeniz varsa veri kurtarma işlemini korkunç hale getirir, ancak yedeklemeler bunun içindir, değil mi?
Perkins
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.