KVM: Thin Provisioning

2025-10-04

Wie kann man den Festplattenspeicherplatz bei Virtualisierung effizient verwalten? Wie wird der Platz gelöschter Dateien wieder frei?.

Im Folgenden ist "Host" der Rechner, auf dem viele virtuelle Maschinen ("Gäste") laufen. Es wird mehrfach von Nullen die Rede sein, womit binäre Nullen, also Bytes mit dem Wert 0x00 gemeint sind.

Problem: Festplattenplatz

Die Festplatte eines Gastes wird i.d.R. als Datei abgelegt, als sogenanntes Disk-Image. Es wäre große Verschwendung, den verfügbaren Platz eines Hosts komplett auf die Gäste aufzuteilen - z.B. eine 1000GB-Partition auf dem Host mit zehn 100GB-Dateien voll zu packen, damit die Clients notfalls so viel benutzen können, obwohl ihnen typischerweise je 20 GB reichen sollten und man somit meist Platz für bis zu 50 Gäste hätte.

Idee: Thin-Provisioning

Das RAW-Format benötigt1 für ein 100GB-Disk-Image auch 100GByte auf der Host-Festplatte. Es empfiehlt sich daher, das QCOW2-Format zu verwenden, da dort erst einmal nur der belegte Platz des Gastes benötigt wird - z.B. 20 GByte. Der Gast "sieht" aber die konfigurierten 100 GByte und kann diese auch verwenden. Dabei wächst die Datei auf dem Host mit - bis die 100GByte erreicht sind. Da dieser Extremfall i.d.R. nicht auftritt, kann man mit etwas Reserve den Gästen in Summe sehr viel mehr Plattenplatz versprechen, als insgesamt vorhanden ist.

Methode 1 (historisch): Festplatte füllen, dann leeren

Eine früher oft beschriebene Vorgehensweise basiert auf dem Wissen, dass im Gast gelöschte Dateien zwar nicht mehr im Verzeichnis auftauchen und ihre Datenblöcke irgendwann überschrieben werden, aber vorläufig noch auf der Festplatte vorhanden sind. Überschreibt man den gesamten als frei deklarierten Platz mit Nullen, so sind die Dateien endgültig vernichtet.
Dann kann man die Festplattendatei optimieren lassen, so dass Blöcke mit Nullen keinen Platz mehr belegen.

So ging man dazu vor:

Nachteile
Vorteil

Methode 2 (modern): discard/TRIM

Hintergrund:

Alle Betriebssysteme haben für SSDs lernen müssen, wie man den nicht benutzten Platz an den Datenträger meldet. So können die Speicherstellen freigegeben werden und von der SSD für das gleichmäßigere Verteilen von Schreibzugriffen genutzt werden können. Der Vorgang wird meist TRIM, Trimmen oder discard genannt. Dies nutzen wir auf dem Gast.

Andererseits können unter Linux in Dateien mehrere Lücken sein, die zwar logisch mit Nullen “gefüllt” sind, aber keinen Platz auf der Festplatte benötigen. Solche Dateien nennt man Sparse-Files. Dies nutzen wir auf dem Host.

So läuft das ideale Zusammenspiel ab:

Damit dies funktioniert muss einerseits der Gast trimmen können und KVM die Freigabe auch verarbeiten:

Gast anpassen (SCSI)

Die virtuelle Festplatte für den Gast muss für ihn eine SCSI-Festplatte an einem VIRTIO-SCSI-Controller sein (ggf. nachträglich geändert - Backup gemacht?), da KVM nur bei dieser den “discard”-Mechanismus beherrscht. Wenn möglich gleich bei Details/Erweiterte Optionen/Mode verwerfen den Eintrag unmap wählen.

KVM ergänzen (unmap)

KVM muss ggf. noch angewiesen werden, wie es mit freigegebenen Speicherbereichen in den Disk-Images umgehen soll: Der Speicher soll im Filesystem des Host-Betriebssystems freigegeben werden - der Fachbegriff ist hier “unmap”. Dies kann man in der Konfiguration des virtuellen Speichers im virt-manager anklicken: bei Details/Erweiterte Optionen/Mode verwerfen den Eintrag unmap wählen.

Gast vollenden (TRIM)

Nun den Gast wieder starten.

Nachbetrachtung

Man muss natürlich damit rechnen, dass obiges Vorgehen immer auch einen Leistungsverlust bei den Festplattenzugriffen bedeutet. Sparse-Files haben nun einmal den Ruf, dass sie im längeren Gebrauch zu einer Fragmentierung der Host-Festplatte führen. Das stört aber nur Benutzer einer echten Festplatte. Mit SSDs ist das kein praktisches Problem. Außerdem kann man jederzeit die unten beschriebene Konvertierung in eine neue Datei durchführen, wodurch auch eine Fragmentierung behoben werden dürfte.

Vorsicht: Bei einer Datensicherung mit z.B. cp oder scp werden die freien Bereiche voll als Nuller übertragen. rsync kann es besser oder man sichert gleich eine optimierte qcow2 datei. Siehe unten:

Handwerkszeug

Test: Dateigrößen

Merke: Das qcow2-Format von KVM erzeugt "sparse"-Dateien. Diese können & werden Lücken haben. Unbenutzter Platz kann logisch als mit Nullen gefüllt angesehen werden. Dies wird dem Host-Betriebssystem (genauer: EXT4-Treiber) mitgeteilt, der das entsprechend vermerkt und dafür keinen Festplattenplatz benötigt. Man kann übrigens auch beliebige Dateien, die Blöcke mit Nullen enthalten, verkleinern, in dem man fallocate -d dateiname aufruft.

ls -hls
du *.qcow2*

So unterscheidet man nun den logischen und den realen Platzbedarf: Der ls-Befehl liefert sowohl die logische Größe, als auch den tatsächlich belegten Platz. Auch du meldet die tatsächliche Belegung.

Die logische Größe ist wichtig, falls man ein Backup ohne weitere Vorkehrungen über’s Netz schiebt: Diese Größe wird übertragen, auch wenn sehr viele Nullen dabei sind. Gezippt sollte das kaum ein Problem sein, kostet aber Zeit. Rsync kann wie immer auch dieses Problem lösen.

Tipp: Konvertieren der QCOW2-Datei

Enthält eine QCOW2-Datei Leerstellen (echte Nullen oder Lücken via sparse-file), so kann man die Datei verkleinern lassen, in dem man sie in eine neue Datei konvertiert. Dabei werden die Leerstellen im qcow2-Format selbst abgebildet und nicht auf Basis von Sparse-Files.

Dies erledigt bei heruntergefahrenem Gast folgende Befehlsfolge (Backup vorhanden?):

mv gast.qcow2 gast.org
qemu-img convert -O qcow2 gast.org gast.qcow2

Dies kann man natürlich auch zum Zweck eines Backups machen:

qemu-img convert -O qcow2 gast.qcow2 /backup/ziel/pfad/gast.qcow2

Wer wirklich auf den Platzbedarf achtet, kann den zusätzlichen Parameter -c zum Komprimieren mitgeben. Dies ist gerade bei Backups sinnvoll. Der Vorgang dauert auch mit mehreren Prozessorkernen deutlich länger. Belegte Sektoren werden jetzt komprimiert, beim späteren Überschreiben aber wieder unkomprimiert abgelegt. Dies führt z.B. zu folgenden Einsparungen:

Bei zukünftigen Schreibzugriffen muss man nun mit leichten Tempoeinbußen rechnen. Auch die Fragmentierung nimmt überdurchschnittlich zu - bei SSDs harmlos.

Geht es jedoch mehr um Performance, so kann man stattdessen beim Konvertieren den Parameter -o preallocation=metadata mit angeben. Das kostet wenig echten Plattenplatz, legt aber bereits alle Metadaten der qcow2-Datei an. Zukünftige Schreibzugriffe sollten entsprechend schnell sein. Ein Vergleich fand sich hier.

Deutlich ausführlicher hier nachzulesen mit vielen weiteren englischen Quellen.

Hier eine ausführlichere englische Quelle zum Trimmen in KVM.

Update: Am 4. Okt 2025 überarbeitet und erneut mit Win10 und Win11 getestet. Veraltetes gekürzt.


  1. hier kann natürlich die Festplattenverwaltung des Hosts selbst wieder optimieren.↩︎

  2. erfolgreich getestet für KVM mit Win10 1909 auf Debian Buster mit virtio-TreiberCD 1.171↩︎

  3. z.B. auf Ubuntu-Xenial KVM mit mehreren Win10 1909 gelungen sowie Win10 22H2 und Win11 24H2 auf Ubuntu 24.01 mit virtio-win-0.1.285.iso↩︎