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.
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 .
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.
Antworten:
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.
Dann mit einem Werkzeug wie
gzip
oder komprimierenxz
. Selbst bei niedrigsten Komprimierungsstufen wird eine lange Reihe von Nullen gut komprimiert:Beachten Sie, dass Sie das Image dekomprimieren müssen, wenn Sie es zurück auf die Festplatte schreiben. Dies wird es "live" dekomprimieren:
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.
Wenn es jedoch wieder auf eine echte Festplatte geschrieben werden soll, müssen Sie es wieder in ein unformatiertes Image konvertieren.
quelle
resize2fs
oderntfsresize
(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.Die Benutzung
resize2fs
ist viel einfacherSie werden zuerst zu e2fsck aufgefordert - so:
(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).
quelle
losetup --find --partscan xxx.img
die Image-Datei als Loop-Gerät einzurichten. Führen Sie dann auslsblk
, um die Partitionen des Loop-Geräts zu suchen.resize2fs
nur fürextN
Typ-Partitionen. Für andere Arten von Partitionen sind andere Tools erforderlich.Ich habe es auch mit qemu-img versucht und es hat wie ein Zauber funktioniert:
Wir ändern die Größe
test.img
, um es 2G (2GB) zu machen .Hat für mich einwandfrei funktioniert.
quelle
df -h
zeigt das Laufen die ursprüngliche Größe. Wie ist das möglich?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 beschrieben2) Überprüfen Sie, mit
lsblk
welchem 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/loop0
und dann eingebenp
. Dies zeigt die Blockgröße und die Endblocknummer der verschiedenen Partitionen an.6) Führen Sie
dd if=/dev/loop0 of=shrunk_image_file.img
die Optionen aus,bs=[BlockSize]
und wenden Sie sie auf diesen Befehl an.count=[EndBlockNumberOfLastLoopPartition+1]
Sie erhalten eine verkleinerte und mit Rechten versehene Bilddatei.quelle