Wie verkleinere ich die Partition einer img-Datei, die aus dd erstellt wurde?

573
MrMas

Ich habe das USB-Laufwerk in eine .imgDatei kopiert dd:

dd if=/dev/sdc of=myimage.img 

Ich möchte die Größe der Partition im Image reduzieren. Ich habe mehrere Methoden ausprobiert und ende immer mit einem Loopback-Image, dessen Partition immer noch die volle Größe des USB hat.

  • Wie kann ich myimage.imgeine kleinere Partition nach dem Loopback-Verfahren ändern ?

  • Muss ich vorher Nullen in den leeren Teil der Partition kopieren?

  • Muss ich defragmentieren, damit leere Bytes gelöscht werden, wenn ich die Bildgröße verkleinere? (Nach allem, was ich gelesen habe, verteilt sich Linux auf die gesamte Partition, sodass ich nicht glaube, dass alle Daten am Ende des Images null Byte sind. Selbst das Schreiben aller Nullen verbraucht die leeren Bytes, wo immer sie liegen.)

HINWEIS: Ich versuche nicht, Speicherplatz zu sparen, daher hilft mir das Zippen nicht.

HINTERGRUND

Ich habe Linux auf einem USB-Laufwerk installiert ext4. Ich beabsichtige, die Installation für mehrere Geräte zu duplizieren. Ich habe dies erfolgreich durchgeführt, möchte aber auf dem gleichen USB-Laufwerk eine schreibgeschützte Partition mit dem System und einer kleinen Partition erstellen, die eine dauerhafte Speicherung ermöglicht. Anstatt meinen USB zu beschädigen, versuche ich, eine Kopie des USB zu ändern. Ich hoffe, wir lassen uns von diesem Hintergrund nicht ablenken.

Kurz gesagt habe ich Folgendes getan:

# Create mount point in current directory sudo mkdir mnt # Loopback mount the image fdisk -l myimage.img sudo mount -o offset=<partion_block_start * block_size> myimage.img mnt # Copy all zeros to remaining space of the image cd mnt sudo dd if=/dev/zero of=filler conv=fsync bs=1M rm filler cd .. 

Zuerst habe ich versucht, partedwie in dieser SuperUser-Antwort und qemu-imgin dieser anderen SuperUser-Antwort beschrieben zu verwenden .

sudo umount mnt parted myimage.img # At parted command prompt (parted) resizepart 1 # Entered my end <target size>. Note that parted uses zero-based  # indexing. This could be your final image size. In my case, the way the # Linux installer worked, the partition started at 1M. (parted) print # I see that the partition is now sized as I expect (parted) exit # Just another sanity check sudo parted -m esp3_007.img unit B print # I see that the partition is now sized as I expect 

Wenn ich versuche, das Image erneut einzuhängen, funktioniert es einwandfrei, aber dfdie Partition wird immer noch in derselben Größe angezeigt. Also habe ich es versucht

qemu-img resize myimage.img <target_size> 

Und jetzt, wenn ich versuche, das Image zu mounten, erhalte ich die Fehlermeldung "mount: falscher fs-Typ, schlechte Option, schlechter Superblock ...".

Dann versuchte ich es mit gpartedder in diesem Off-Site-Beitrag beschriebenen Verwendung . Die grafische Benutzeroberfläche zeigte eine vollständige Partition an, es sei denn, ich lief partedzuerst. Selbst dann ließ mich die GUI die Größe der Partition nicht ändern.

Um zu versuchen, die Partitionsgröße zu verringern, und mit einer neuen Kopie von myimage.imgIch zu beginnen, habe ich versucht fdisk, in dieser AskUbuntu-Antwort beschrieben

sudo fdisk myimage.img Command (m for help): d Command (m for help): n Command action e extended p primary partition (1-4) p Partition number (1-4, default 1): 1 # defaults on the rest seemed to be correct in my case. 

Beim Einhängen der Partition wurde immer noch dieselbe Größe angezeigt.

0
* HINWEIS: Ich versuche nicht, Speicherplatz zu sparen * - warum dann die Mühe machen? Nur das Kopieren von Dateien funktioniert A-OK für Linux und fügt dann einen Bootloader hinzu Xen2050 vor 5 Jahren 0
Wie bereits erwähnt, muss ich die Partitionsgröße ändern, um eine weitere Partition hinzuzufügen, ohne Linux neu zu installieren. MrMas vor 5 Jahren 0
Sie müssen nicht neu installieren, kopieren Sie einfach die Dateien + grub / etc Xen2050 vor 5 Jahren 0

1 Antwort auf die Frage

4
grawity

Auf Schleifenbildern

Vergessen Sie zunächst offset=, verwenden Sie losetup --partscandie Partition und laden Sie sie einfach über ein /dev/loop0p1.

# losetup --partscan /dev/loop0 myimage.img # lsblk # mount /dev/loop0p1 /mnt 

Um den leeren Speicherplatz in einer Partition effizient zu löschen, führen fstrimSie das in einer Schleife eingebundene Dateisystem wie auf einer SSD aus. (Dadurch wird die Bilddatei tatsächlich spärlich.)

# fstrim -v /mnt 

Beim Ändern der Größe von Partitionen

Für den Moment müssen Sie jedoch keinen leeren Raum leeren oder so etwas tun. Es ist völlig unerheblich, ob der etwa beschnittene Bereich mit Nullen oder mit alten Datenblöcken gefüllt wird.

Stattdessen müssen Sie genau dasselbe tun, wie Sie es mit ext4 auf einer echten Festplatte tun würden - Sie müssen jede Ebene von innen nach außen verkleinern. Sie können Schritte nicht überspringen, nur weil es sich um ein Bild handelt.

Um eine Partition zu verkleinern, die ein Dateisystem enthält, müssen Sie das Dateisystem zunächst anweisen, sich selbst zu verkleinern. Bei ext2 / 3/4 erfolgt dies mit resize2fs. Dadurch werden Daten aus dem Bereich verschoben, in dem Sie sich gerade befinden, und die neuen Grenzen werden als Teil der Metadaten des Dateisystems gespeichert. (Ich vermute, das meinte man mit "Defragmentieren".)

Erst wenn das Dateisystem verkleinert wurde, können Sie auch die Partition verkleinern, die es enthält. Dies kann über parted oder fdisk erfolgen, indem Sie einfach die Endadresse der Partition ändern.

Randbemerkung: Sie sollten in der Lage sein, GParted zu verwenden, um die Größe des Dateisystems und der Partition in einem Schritt zu ändern - sofern dies das Arbeiten mit Schleifengeräten unterstützt. Dies kann von der Version von GParted abhängen. (Das CLI parted kann Dateisysteme jedoch nicht verkleinern, die Partition wird nur abgeschnitten.)

Sobald das Dateisystem und die Partition geändert wurden, können Sie das gesamte Image, das sie enthält, abschneiden. Trennen Sie dazu zuerst das Loop-Gerät und verwenden Sie es truncate --size=...in Ihrer Image-Datei.

(Um sicher zu gehen, ohne sorgfältige Berechnungen durchführen zu müssen, würde ich das Dateisystem etwas mehr verkleinern, als für die Erstellung eines "Pufferbereichs" erforderlich ist). Wenn ich beispielsweise ein 4-GB-Image wollte, würde ich das Dateisystem auf 3 GB, die Partition, verkleinern auf 3,5 GB, und kürzen Sie dann das Image auf 4 GB. Wachsen Sie dann alles in umgekehrter Reihenfolge auf, um den 'Puffer'-Speicherplatz zu füllen.)

Übrigens funktionierte "gparted" aus ähnlichen Gründen nicht. Die anderen Befehle funktionierten nicht: "gparted" funktioniert nicht direkt in Image-Dateien. Wenn Sie zurückgehen, "losetup" verwenden, wie in dieser Antwort beschrieben, und dann "gparted" unter "/ dev / loopx" ausführen, können Sie die Größe ändern. MrMas vor 5 Jahren 0