Wie konvertiere ich ein Linux-Image in eine Sparse-Datei?


12

Ich habe eine Reihe von Disk-Images, die mit ddrescue auf einer EXT-Partition erstellt wurden, und ich möchte deren Größe reduzieren, ohne Daten zu verlieren, während sie noch mounten können.

Wie kann ich den leeren Bereich im Dateisystem des Bildes mit Nullen füllen und die Datei dann in eine Datei mit geringer Dichte konvertieren, damit dieser leere Bereich nicht tatsächlich auf der Festplatte gespeichert wird?

Zum Beispiel:

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

Dies enthält jedoch nur 50 G reale Daten, sodass die zweite Messung viel kleiner sein sollte.

Dies wird angeblich den leeren Raum mit Nullen füllen:

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

Wenn jedoch Dateien mit geringer Dichte transparent behandelt werden , wird möglicherweise eine Datei mit geringer Dichte erstellt, ohne dass etwas auf die virtuelle Festplatte geschrieben wird, was mich ironischerweise daran hindert, das Image der virtuellen Festplatte selbst in eine Datei mit geringer Dichte zu verwandeln. :) Macht es?

Hinweis: Funktioniert aus irgendeinem Grund, sudo dd if=/dev/zero of=./zero.filewenn catdies nicht auf einem gemounteten Disk-Image der Fall ist.


2
Durch das Schreiben von Nullen in eine Datei wird keine Datei mit geringer Dichte erstellt. Es ist ein anderes Konzept. Wenn Sie eine Datei mit geringer Dichte suchen / lesen, wenn das Betriebssystem feststellt, dass der Datenblock nicht wirklich vorhanden ist (die Blockliste ist für Daten in dieser Region leer), füllt das Betriebssystem den Lesepuffer automatisch mit null Byte.
Hotei

Hinweis: Funktioniert sudo cat /dev/zero > zero.filenicht, da Ihre Bash (ausgeführt wie Sie, nicht root) die Umleitung vor dem Ausführen des sudoBefehls ausführt . Siehe unix.stackexchange.com/questions/1416/…
Fritz

Antworten:


19

Erstens werden spärliche Dateien nur dann transparent behandelt, wenn Sie suchen, nicht wenn Sie Nullen schreiben.

Zur Verdeutlichung das Beispiel aus Wikipedia

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

hat nicht schreiben keine Nullen, wird die Ausgabedatei öffnen, suchen (springen) 5 MB und dann schreiben Null Nullen (dh nichts). Dieser Befehl ( nicht aus Wikipedia)

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

schreibt 5 MB Nullen und erstellt keine Datei mit geringer Dichte!

Infolgedessen wird eine Datei, die bereits nicht dünn ist, später nicht auf magische Weise dünn.

Zweitens, um eine Datei mit vielen Nullen spärlich zu machen, müssen Sie cp es

cp --sparse=always original sparsefile

oder Sie können auch die Option --sparse von tar oder rsync verwenden .


1
Laut Wikipedia wird durch das Schreiben von Nullen mit dd eine Datei mit geringer Dichte erstellt. Können Sie erklären, was "Suchen" bedeutet?
Endolith

1
Was ist dann mit Katze? In der Manpage gibt es nichts über spärliche Dateien, also gehe ich davon aus, dass cat /dev/zero > zero.filees vollkommen in Ordnung ist, den leeren Raum mit Nullen zu füllen.
Ludwig Weinzierl

2
@endolith: Meine Antwort wurde aktualisiert, um zu verdeutlichen, welchen Unterschied es gibt, ddNullen zu schreiben oder zu suchen.
Mihi

2
@Ludwig Weinzierl: Ja, dieser catBefehl füllt Ihre gesamte Festplatte (oder zumindest den Betrag, der nicht für root oder nach Kontingenten reserviert ist) mit "echten" Nullen und erstellt keine spärlichen Dateien.
Mihi

1
@endolith Sie benötigen zusätzlichen Platz, ja. Da Sie den Tarball jedoch komprimieren können, benötigen Sie nur Speicherplatz für die Originaldatei und eine komprimierte Version der Sparse-Datei.
Mihi

12

Der einfachste Weg, eine Datei an Ort und Stelle zu sparsifizieren, ist möglicherweise die Verwendung des fallocateDienstprogramms wie folgt:

fallocate -v --dig-holes {file_name}

fallocate (1) wird vom util-linux- Paket unter Debian bereitgestellt .


1
Aus irgendeinem Grund fallocate --dig-holesergab sich eine 103GiB-Datei aus dem 299GiB-Original, während cp --sparse=alwaysich 93GiB erhielt - alle mit der gleichen SHA1-Summe (Größen über du -B1Gvs überprüft du --apparent-size -B1G). So fallocatescheint schlechtere Ergebnisse zu geben.
Ruslan

3

Der Vollständigkeit halber meine Antwort bearbeiten:

  1. Ballon leerer FS-Raum mit Nullen (WARNUNG: Dies ändert Ihr Disk-Image):

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

Angenommen, es gibt / dev / loop1 als Festplatte an und es gibt nur eine Partition. Andernfalls müssen wir dies für jede Partition mit einbaubarem FS wiederholen (Swap-Partition ignorieren usw.).

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

Lassen Sie es mit ENOSPC zum Scheitern kommen.

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

  1. In ein spärliches Bild kopieren:

'dd' hat die Option, eine Datei mit Nullen in eine Datei mit geringer Dichte zu konvertieren:

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



1
Ja, diese Option stammt nicht aus der Zeit, als OP gefragt wurde. Dies war mehr von "Hinterlasse eine Brotkrume für andere Suchende" ... :-)
Lam Das

1
Je nach Dateisystemtyp ist dies zerofreemöglicherweise schneller als das Mounten und Schreiben von Nullen in das Dateisystem, und das Festplatten-Image wächst weniger, wenn es bereits viele Nullen enthält.
Mihi

2

Meinen Sie damit, dass Ihr von ddrescue erstelltes Image beispielsweise 50 GB groß ist und in Wirklichkeit etwas viel weniger ausreichen würde?

Wenn dies der Fall ist, können Sie nicht einfach zuerst ein neues Bild mit dd erstellen:

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

und erstellen Sie dann ein Dateisystem darin:

mkfsofyourchoice some_image.img

dann einfach das Image mounten und alles vom alten auf das neue Image kopieren? Würde das für dich funktionieren?


2

PartImage kann Disk-Images erstellen, in denen nur die verwendeten Blöcke eines Dateisystems gespeichert werden, wodurch der erforderliche Speicherplatz drastisch reduziert wird, indem nicht verwendete Blöcke ignoriert werden. Ich glaube nicht, dass Sie die resultierenden Bilder direkt mounten können, aber gehen Sie:

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

Sollte produzieren, was Sie wollen (könnte sogar möglich sein, den letzten Schritt zu halten, habe es nicht versucht).


1
Leider können die von partimage erstellten Bilder nicht gemountet werden, ohne sie erneut zu erweitern, sodass sie nur für Archivierungszwecke geeignet sind.
Perkins

0

Es gibt jetzt ein Tool namens virt-sparsify, das dies erledigt . Es füllt den leeren Raum mit Nullen und kopiert das Bild dann in eine Datei mit geringer Dichte. Es erfordert jedoch die Installation vieler Abhängigkeiten.


-2

Ich vermute, Sie benötigen ein benutzerdefiniertes Programm, das auf diese Spezifikation geschrieben ist, wenn Sie dies WIRKLICH tun möchten. Aber ist es...?

Wenn Sie tatsächlich viele Null-Bereiche haben, wird jedes gute Komprimierungswerkzeug diese erheblich reduzieren. Der Versuch, spärliche Dateien zu schreiben, funktioniert nicht in allen Fällen. Wenn ich mich richtig erinnere, belegen selbst spärliche Dateien mindestens 1 Block Ausgabespeicher, wobei der Eingabeblock JEDE Bits enthält, die nicht Null sind. Beispiel: Angenommen, Sie hatten eine Datei mit durchschnittlich 1 Bit ungleich Null pro 512-Byte-Block. Sie kann nicht "spärlich" geschrieben werden. Übrigens gehen keine Daten verloren, wenn Sie die Datei mit zip, bzip, bzip2 oder p7zip komprimieren. Sie sind nicht wie verlustbehaftete MPEG- oder JPEG-Komprimierung.

Wenn Sie jedoch zufällige Suchvorgänge in die Datei durchführen müssen, ist die Komprimierung möglicherweise schwieriger als es sich lohnt, und Sie kehren zum spärlichen Schreiben zurück. Ein kompetenter C- oder C ++ - Programmierer sollte in der Lage sein, so etwas in einer Stunde oder weniger zu schreiben.


Interessant - eine Abwertung, aber ich stelle fest, dass es keine Widerlegung dessen gibt, was ich geschrieben habe. Wenn es korrekt, aber nicht hilfreich ist, ist dies kein Grund zur Ablehnung. Wenn es nicht genau und nicht hilfreich ist, hat es es verdient.
Hotei

Ich sehe an anderer Stelle, dass das OP eine Frage bezüglich der Montage komprimierter Bilder hatte. Ich gehe davon aus, dass dies eine Fortsetzung dieses Threads ist. Ich weiß, dass ich jetzt sehen kann, warum mein Vorschlag zur Komprimierung nicht akzeptiert wurde. Ein einfaches C-Programm ist immer noch eine einfache Möglichkeit, Dateien mit geringer Dichte zu erstellen. ABER - Mit dem (nicht spezifizierten) Betriebssystem können Sie eine spärliche ISO mounten. So wählerisch der Ubuntu ISO-Mounter auch ist, ich bin mir nicht hundertprozentig sicher, dass das auch funktionieren wird ... aber auf jeden Fall viel Glück.
Hotei

4
Warum das Rad neu erfinden? cp --sparse=alwaysmacht die Arbeit gut
mihi

@mihi: Das ist eine gute Idee. Ich wusste nichts über die Sparse-Option, da sie nicht in BSD- Varianten ( freebsd.org/cgi/… ) verfügbar ist, und ich hatte (bis heute) nie die Anforderung, eine Linux-Manpage für cp aufzurufen .
Hotei

Eine Möglichkeit, Ihre komprimierten Images zu erstellen und auch zu mounten, besteht darin, sie einfach in einem Dateisystem zu speichern, das die native Komprimierung unterstützt. Macht die Datenwiederherstellung schrecklich, wenn Sie einen Laufwerksabsturz haben, aber dafür sind Backups gedacht, oder?
Perkins
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.