TEILEN

Im Artikel SD-Karte eines Raspberry Pi als Image klonen, sichern und zurückspielen hatte ich schon einmal beschrieben, wie man eine RasPi-Installation von der Speicherkarte sichert und zurückspielt — No Shit, Sherlock. Eine Frage tauchte dabei jedoch desöfteren auf: Die Image-Datei wird genauso groß, wie die Speicherkarte, auch wenn auf dieser noch viel Platz frei ist. Der „leere“ Platz wird quasi mit ins Image gepackt. Somit muss die neue Speicherkarte mindestens so groß sein wie die alte. Zudem belegt ein für später archiviertes Image viel Platz. Wie also kann man die Luft aus Image eines Raspberry Pi rauslassen?

Auf GitHub bin ich neulich über das Skript PiShrink gestolpert, das genau diese Aufgabe übernimmt. Das kleine Programm schnappt sich ein RasPi-Image, reduziert die Partitionsgröße auf das nötige Minimum und baut in das archivierte RasPi-System zudem gleich ein Skript ein, das beim nächsten Booten des Systems auf „echter“ Hardware die Partition auf den maximalen Speicherplatz ausgedehnt. So lässt sich Image eines Raspbian-Systems von mehreren Gigabyte schnell auf ein paar hundert Megabyte verkleinern, ohne dass man viel Aufwand treiben muss. Auch beim Zurückspielen des komprimierten Systems spart man sich Arbeit, da das Dateisystem eben beim Starten des Raspberry Pi automatisch wieder auf die volle Größe ausgedehnt wird.

$ mkdir ~/bin
$ wget https://raw.githubusercontent.com/Drewsif/PiShrink/master/pishrink.sh -P ~/bin
$ chmod +x ~/bin/pishrink.sh

Da es sich bei PiShrink um ein simples Bash-Skript handelt, ist die Installation des Programms nicht sonderlich kompliziert: Man muss das Skript lediglich aus dem Netz herunterladen und die Rechte entsprechend setzen. Ich persönlich packe solche Skripte nach ~/bin ins Homeverzeichnis. Das System sollte diesen Ordner eigentlich automatisch in den $PATH eures Benutzers aufnehmen, sodass man das Kommando ohne Pfadangabe von überall aus im System aus aufrufen können sollte. Sollte dies bei euch nicht der Fall sein, gibt es im Netz an vielen Orten entsprechende Informationen zum Erweitern der Umgebungsvariablen (dort dreht es sich um Ubuntu, das Vorgehen ist bei anderen Distributionen jedoch nicht viel anders).

PiShrink komprimiert Raspberry Pi-Images

Nun müsstet ihr PiShrink-Skript mit der Eingabe eines beherzten pishrink.sh aus dem Terminal heraus aufrufen können. Ohne die Angabe eines Images gibt das Skript lediglich seine Syntax aus: Im Endeffekt beschränkt sich das Kommando auf die Angabe einer Image-Datei und optional eines weiteren Dateinamens eines neu zu erstellenden Images, falls PiShrink das Original-Image des Raspberry Pi unangetastet lassen soll. Belässt man es bei einem Dateiname, bearbeitet PiShrink das genannte Image.

Raspberry Pi und Zubehör kaufen (Anzeige)
KomponenteBemerkungPreise (03.2017)
Raspberry Pi 3 Model B Inkl. WLAN und Bluetooth Etwa 40 Euro
Raspberry Pi Zero W Inkl. Gehäuse Etwa 26 Euro
Gehäuse für RPi3 Diverse Modelle zur Wahl Etwa 7 Euro
Netzteil Ideal mit mind. 2500 mA Etwa 10 Euro
MicroSD-Speicherkarte Mind. 8 GByte, Class 10 Ab 8,90 Euro
HDMI-Kabel CEC-fähig Etwa 5 Euro
Optional
Raspberry Pi-Touchscreen 7 Zoll mit 800 x 480 Pixeln Etwa 85 Euro
Raspberry Pi-Frame für Display Fünf verschiedene Farben Etwa 20 Euro
Logitech K400 Plus Touch Schnurlose Tastatur mit Touchpad Etwa 35 Euro
USB-WLAN-Stick 150 Mbit/s, IEEE802.11b/g/n Etwa 7 Euro

Der einzige Schalter -s ist dann wichtig, wenn man das Image eines RasPi-System verkleinern möchte, das nicht auf einem Raspbian basiert — also beispielsweise die Kodi-Distributionen LibreELEC oder OpenELEC. Genauer gesagt muss man sagen, dass der Schalter PiShrink anweist das Ausdehnen des Systems zu unterlassen. Dazu trägt PiShrink eigentlich ein Kommando in die Datei /etc/rc.local ein, die Raspbian beim Booten automatisch ausführt. Diese Datei gibt es jedoch bei LibreELEC (und manch anderer Distributionen) nicht.

### Hilfe zu PiShrink aufrufen:
$ pishrink.sh
Usage: /home/toff/bin/pishrink.sh [-s] imagefile.img [newimagefile.img]
### Vorhandenes RasPi-Image verkleinern:
$ sudo pishrink.sh raspberry-pi.img
### Image verkleinern und Original behalten:
$ sudo pishrink.sh raspberry-pi.img raspberry-pi_pishrink.img
### Automatisches Vergrößern der Partition deaktivieren:
$ sudo pishrink.sh -s raspberry-pi.img raspberry-pi_klein.img

Wie kommt das nun alles Zusammen: Als Beispiel verwende ich hier eine aktuelle Installation von Raspbian Lite auf einer 16 GByte großen SD-Karte. Diese legt man nun in den Kartenleser ein, holt sich mit lsblk die Geräte-ID und sichert dann mit dd das Image auf die Festplatte. Die Image-Datei liegt danach unter dem Namen raspberry-pi.img rund 16 GByte schwer auf der Festplatte — obwohl das Image eigentlich größtenteils leer ist. Außer dem Raspbian-System und ein paar Konfigurationen befinden sich keine Daten auf dem System.

$ lsblk
NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
[...]
sdd      8:48   1  14,9G  0 disk 
├─sdd1   8:49   1    63M  0 part /run/media/[...]/boot
└─sdd2   8:50   1  14,8G  0 part /run/media/[...]/0aed834e-8c8f-412d-a276-a26
$ sudo dd if=/dev/sdd of=~/raspberry-pi.img
15894831104 Bytes (16 GB, 15 GiB) kopiert, 210 s, 75,7 MB/s     
31116288+0 Datensätze ein
31116288+0 Datensätze aus
15931539456 Bytes (16 GB, 15 GiB) kopiert, 210,459 s, 75,7 MB/s
$ ls -alh ~/raspberry-pi.img 
-rw-r--r-- 1 root root 15G 24. Feb 21:48 raspberry-pi.img

Anschließend ruft man nun PiShrink entsprechend auf — Da es sich um ein Raspbian-System handelt, lasse ich die Option -s weg. PiShrink kopiert sodann das Image (achtet daher darauf ausreichend freien Festplattenspeicher zu haben), mountet die Kopie dann in ein temporäres Verzeichnis in /tmp und reduziert abschließend die Größe des Images von Anfangs knapp 16 GByte auf nun nur noch 1,6 GByte. Der Erfolg hängt natürlich davon ab, wie viel echte Daten auf der SD-Speicherkarte des Raspberry Pi enthalten waren.

$ sudo pishrink.sh raspberry-pi.img raspberry-pi_pishrink.img
Copying raspberry-pi.img to raspberry-pi_pishrink.img...
Creating new /etc/rc.local
e2fsck 1.43.4 (31-Jan-2017)
Durchgang 1: Inodes, Blöcke und Größen werden geprüft
Durchgang 2: Verzeichnisstruktur wird geprüft
Durchgang 3: Verzeichnisverknüpfungen werden geprüft
Durchgang 4: Referenzzähler werden überprüft
Durchgang 5: Zusammengefasste Gruppeninformation wird geprüft
/dev/loop2: 35832/959616 Dateien (0.2% nicht zusammenhängend), 321790/3872384 Blöcke
resize2fs 1.43.4 (31-Jan-2017)
resize2fs 1.43.4 (31-Jan-2017)
Die Größe des Dateisystems auf /dev/loop2 wird auf 382429 (4k) Blöcke geändert.
Start von Durchgang 2 (max = 40814)
Blöcke werden verschoben     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Start von Durchgang 3 (max = 119)
Die Inode-Tabelle wird gelesenXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Start von Durchgang 4 (max = 3178)
Die Inode-Referenzen werden aktualisierXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX-
Das Dateisystem auf /dev/loop2 is nun 382429 (4k) Blöcke lang.

Shrunk raspberry-pi_pishrink.img from 15G to 1,6G
$ ls -alh raspberry-pi*
-rw-r--r-- 1 root root  15G 27. Feb 11:08 raspberry-pi.img
-rw-r--r-- 1 root root 1,6G 27. Feb 11:30 raspberry-pi_pishrink.img

Geschrumpftes RasPi-Image wiederherstellen

Zum Test soll das ursprünglich auf einer 16 GByte großen SD-Karte installierte Raspbian-System auf eine MicroSD mit nur 8 GByte umziehen. Dazu schreibe ich das mit PiShrink verkleinerte Image nun also wieder mit dd zurück, packe die Karte in den Raspberry Pi und starte das geschrumpfte System. Um den Speicherplatz auf die komplette Speicherkarte auszudehnen, startet das System automatisch beim ersten Bootvorgang einmal neu durch. Am Ende landet man dann wieder im gewohnten Raspbian-System, ein df -h zeigt, dass das System jetzt wieder die komplette Karte verwendet.

$ lsblk
NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
[...]
sdd      8:48   1   7,4G  0 disk 
├─sdd1   8:49   1    63M  0 part /run/media/[...]/boot
└─sdd2   8:50   1   7,3G  0 part /run/media/[...]/0aed834e-8c8f-412d-a276-a26
$ sudo dd if=raspberry-pi_pishrink.img of=/dev/sdd bs=1M; sync
1560+1 Datensätze ein
1560+1 Datensätze aus
1636684288 Bytes (1,6 GB, 1,5 GiB) kopiert, 116,203 s, 14,1 MB/s
pi@raspberrypi:~ $ df -h
Dateisystem    Größe Benutzt Verf. Verw% Eingehängt auf
/dev/root       7,2G    990M  6,0G   14% /
devtmpfs        459M       0  459M    0% /dev
tmpfs           463M       0  463M    0% /dev/shm
tmpfs           463M    6,2M  457M    2% /run
tmpfs           5,0M    4,0K  5,0M    1% /run/lock
tmpfs           463M       0  463M    0% /sys/fs/cgroup
/dev/mmcblk0p1   63M     21M   42M   33% /boot
PiShrink reduziert das Image eines Raspberry Pi-Systems auf die minimale Größe.

Sichert man ein Raspberry Pi-System, das nicht auf Raspbian basiert und das auf eine /etc/rc.local verzichtet (wie etwa schon angesprochen die Kodi-Distributionen LibreELEC oder OpenELEC), dann bekommt ihr beim Schrumpfen des Images die folgende Fehlermeldungen. In diesem Fall müsstet ihr eben mit der Option -s verhindern, dass PiShrink das Kommando zum Vergrößern der Datenpartition in diese Datei einbaut. Dann läuft das Schrumpfen auch ohne eine Fehlermeldung durch.

### Fehlermeldungen beim Schrumpfen eines LibreELEC-Images:
$ sudo pishrink.sh libreelec.img
[...]
md5sum: /tmp/tmp.4ornQ3Va4y/etc/rc.local: Datei oder Verzeichnis nicht gefunden
/home/[...]/bin/pishrink.sh: Zeile 63: [: !=: Einstelliger (unärer) Operator erwartet.
[...]
### LibreELEC, OpenELEC und Co. schrumpft man besser so:
$ sudo pishrink.sh -s libreelec.img
Skipping autoexpanding process...
e2fsck 1.43.4 (31-Jan-2017)
/dev/loop2: Journal wird wiederhergestellt
Durchgang 1: Inodes, Blöcke und Größen werden geprüft
Durchgang 2: Verzeichnisstruktur wird geprüft
Durchgang 3: Verzeichnisverknüpfungen werden geprüft
Durchgang 4: Referenzzähler werden überprüft
Durchgang 5: Zusammengefasste Gruppeninformation wird geprüft
/dev/loop2: 861/1810432 Dateien (1.0% nicht zusammenhängend), 252448/7235584 Blöcke
resize2fs 1.43.4 (31-Jan-2017)
resize2fs 1.43.4 (31-Jan-2017)
Die Größe des Dateisystems auf /dev/loop2 wird auf 49976 (1k) Blöcke geändert.
Start von Durchgang 2 (max = 15759)
Blöcke werden verschoben     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Start von Durchgang 3 (max = 884)
Die Inode-Tabelle wird gelesenXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Start von Durchgang 4 (max = 143)
Die Inode-Referenzen werden aktualisierXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX-
Das Dateisystem auf /dev/loop2 is nun 49976 (1k) Blöcke lang.

Shrunk libreelec.img from 7,5G to 563M

Das auf die Speicherkarte zurückgeschriebene System wird nun jedoch nicht mehr automatisch vergrößert. LibreELEC (und meines Wissens nach auch OpenELEC) bietet in seinen Menüs auch keine „Vergrößere den Speicherplatz bitte auf die maximale Partitionsgröße“-Option. Die in das System integrierte Routine ist nur für eine frisch auf die SD-Karte kopierte Installation gedacht. Mit Tools wie Gparted lässt sich die Partitionsgröße jedoch schnell wieder korrigieren, allerdings eben nur von Hand. GParted gibt es nur für Linux, Windows-Nutzer können das Programm jedoch bei Bedarf über eine Live-CD oder einen Live-USB-Stick starten

Mit Tools wie GParted lässt sich die Partitionsgröße schnell wieder anpassen.

4 KOMMENTARE

  1. Genial, genau das, was ich lange Zeit gesucht habe.

    Nach voller Einrichtung meines OMV-Nas-Servers auf dem Raspberry will ich das Image sichern und später auch auf einer 8Gb-Karte (damals hatte ich nur eine 16er zur Hand) notfalls wiederherstellen können.

    Vielen Dank!

  2. Danke für den Artikel. Hab diese Seite zufällig gefunden und bin froh darüber. Man erfährt hier immer wieder mal Interessante und nützliche Sachen.

  3. Hallo Christoph, seit Jahren schaue ich in unregelmäßigen Abständen auf deiner Seite vorbei. Nahezu jedes Mal entdecke ich in deinen dann zurückliegenden veröffentlichten Einträgen Neues und Interessantes für mich. Vielen Dank, dass du pishrink entdeckt und uns an dieser Entdeckung hast teilnehmen lassen!! Das Skript ist gerade dabei ein Raspi-Image von einer 16 GB micro SDHC-Karte zu verkleinern. Grüße, M.

    Link: http://www.forum-raspberrypi.de/Thread-raspbian-image-verkleinern-mit-pishrink

HINTERLASSEN SIE EINE ANTWORT

Please enter your comment!
Please enter your name here