Wie ändert man die Größe einer mit dd erstellten IMG-Datei?


19

Ich habe ein DD-Image von einer 4-GB-SD-Karte mit zwei Partitionen. Diese beiden Partitionen belegen nur ca. 800 MB. Daher möchte ich das Bild verkleinern.

Kennt jemand eine Möglichkeit, den "freien Speicherplatz" aus der img-Datei zu entfernen?


Vielleicht möchten Sie hinzufügen, was das gewünschte Ergebnis ist. dh: Bild zurück auf die Karte, um es auf CD zu speichern.
Wayne

Antworten:


8

Stellen Sie zunächst sicher, dass der freie Speicherplatz tatsächlich leer ist und keine Reste gelöschter Dateien enthält. Der einfachste Weg, dies zu erreichen, besteht darin, eine riesige Datei auf der Festplatte zu erstellen, die nur null Bytes enthält, und diese dann zu löschen.

# losetup --find --partscan foo.img
# lsblk
NAME      MAJ:MIN RM    SIZE RO TYPE MOUNTPOINT
loop0       7:0    0   4096M  0 loop 
├─loop0p1 259:0    0   2048M  0 loop 
└─loop0p2 259:1    0   2048M  0 loop 
# for part in /dev/loop0p*; do
    mount $part /mnt
    dd if=/dev/zero of=/mnt/filler conv=fsync bs=1M
    rm /mnt/filler
    umount /mnt
  done
dd: error writing ‘/mnt/filler’: No space left on device
dd: error writing ‘/mnt/filler’: No space left on device
# losetup --detach /dev/loop0

Dann mit einem Werkzeug wie gzipoder komprimieren xz. Selbst bei niedrigsten Komprimierungsstufen wird eine lange Reihe von Nullen gut komprimiert:

# ls -s
4096M foo.img
# gzip foo.img
# ls -s
11M foo.img.gz

Beachten Sie, dass Sie das Image dekomprimieren müssen, wenn Sie es zurück auf die Festplatte schreiben. Dies wird es "live" dekomprimieren:

# cat foo.img.gz | gunzip | dd of=/dev/sda

Beachten Sie, dass das Ausgabegerät (sda) muss ausreichend groß sein , die passen Originalbild, andernfalls Daten verloren gehen oder beschädigt werden.


Wenn Sie das Image weiterhin verwenden möchten, z. B. mit einer virtuellen Maschine, können Sie das Raw-Image in eines der von der Virtualisierungssoftware verwendeten Image-Formate konvertieren. zB qcow2 für Qemu, VDI für VirtualBox oder VMDK für VMware.

Beachten Sie, dass dies immer noch Sie das Bild zur Vorbereitung erfordert durch den freien Raum Reinigung der obigen Verfahren.

# qemu-img convert -f raw -O qcow2 foo.img foo.qcow

# qemu-img convert -f raw -O vmdk foo.img foo.vmdk

Wenn es jedoch wieder auf eine echte Festplatte geschrieben werden soll, müssen Sie es wieder in ein unformatiertes Image konvertieren.


1
Wie können Sie sicherstellen, dass alle Dateien, die derzeit auf den Partitionen gespeichert sind, nicht physisch auf der Festplatte verstreut sind?
Valerio Santinelli

weil ich nehme an, dass Dateien nicht sequenziell auf die Festplatte geschrieben werden und wenn sich eine Datei am Ende des Speichers befindet, werde ich den Inhalt dieser Datei verlieren, wenn ich die Größe reduziere.
Valerio Santinelli

Denn das OP fragt, wie man ein Disk-Image verkleinert, ohne Daten zu verlieren. Wenn Sie ein Bild bei einer bestimmten Größe abschneiden, können Sie nicht sicher sein, dass die Daten erhalten bleiben.
Valerio Santinelli

@ValerioSantinelli: Wo genau schlage ich vor, das Bild abzuschneiden?
Grawity

1
@ValerioSantinelli: Verwenden Sie das entsprechende Tool zur Größenänderung des Dateisystems für Ihr Dateisystem, z. B. resize2fsoder ntfsresize(Linux hat kein Tool für FAT), bevor Sie es auf das kleinere Gerät schreiben, oder erstellen Sie ein neues Dateisystem und kopieren Sie nur die Dateien.
Grawity

22

Die Benutzung resize2fsist viel einfacher

resize2fs -M xxx.img

Sie werden zuerst zu e2fsck aufgefordert - so:

e2fsck -f -y xxx.img

(Bild darf NICHT gemountet werden!)

Hinweis: Dies funktioniert nur, wenn das Image von einer einzelnen Partition stammt, wenn es sich um ein ganzes Blockgerät mit mehreren Partitionen handelt (siehe Antwort oben).


Nur ein Hinweis: Verwenden Sie für mehrere Partitionen, um losetup --find --partscan xxx.imgdie Image-Datei als Loop-Gerät einzurichten. Führen Sie dann aus lsblk, um die Partitionen des Loop-Geräts zu suchen.
Yihui Xiong

Es sieht so aus, als würde es bei einem ISO-Image, das ein Betriebssystem enthält, nicht funktionieren. Nach der Größenänderung bootet das System nicht mehr.
SR

@ SR Linux Betriebssystem?
Rolf

1
Dies ist eine sehr schöne Antwort, aber resize2fsnur für extNTyp-Partitionen. Für andere Arten von Partitionen sind andere Tools erforderlich.
Rolf

2

Ich habe es auch mit qemu-img versucht und es hat wie ein Zauber funktioniert:

qemu-img resize test.img 2G

Wir ändern die Größe test.img, um es 2G (2GB) zu machen .

Hat für mich einwandfrei funktioniert.


1
Genial, hat auch für mich einwandfrei funktioniert und ein Raspbian-Bild komprimiert. voll funktionsfähig!
ffleandro

Nun, alles funktioniert, aber nach dem Booten df -hzeigt das Laufen die ursprüngliche Größe. Wie ist das möglich?
ffleandro

Offenbar wird die Partitionstabelle von qemu-img nicht komprimiert. Wie komprimiert es die .img-Datei?
ffleandro

Ich kann die Größe einer .img-Disk auf 1 MB ändern, wodurch das Disk-Image definitiv beschädigt wird. Irgendeine Idee, um die Größenänderung sicherer zu machen?
Lesca

1

Ich habe den gparted-Ansatz mit meinem Ubuntu 16.10-Computer verwendet:

1) Ordnen Sie die IMG-Datei der nächsten verfügbaren Loop-Partition mit zu losetup, wie in den vorherigen Beiträgen beschrieben

2) Überprüfen Sie, mit lsblkwelchem ​​Loop-Laufwerk Ihre Image-Datei verknüpft ist, z/dev/loop0

3) Ausführen sudo gparted /dev/loop0

4) Verkleinern Sie die Schleifenpartition (en) nach Bedarf. Bitte stellen Sie sicher, dass diese Partitionen nicht gemountet sind.

5) Ausführen fdisk /dev/loop0und dann eingeben p. Dies zeigt die Blockgröße und die Endblocknummer der verschiedenen Partitionen an.

6) Führen Sie dd if=/dev/loop0 of=shrunk_image_file.imgdie Optionen aus, bs=[BlockSize]und wenden Sie sie auf diesen Befehl an. count=[EndBlockNumberOfLastLoopPartition+1]Sie erhalten eine verkleinerte und mit Rechten versehene Bilddatei.

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.