LVM

Aus wiki.archlinux.de
Wechseln zu: Navigation, Suche

Übersicht

Der Logical Volume Manager, kurz LVM, ist eine Alternative zu den klassischen Partitionen um Massenspeicher wie Festplatten logisch zu unterteilen. LVM bietet dabei gegenüber normalen Partitionen viele Vorteile, aber auch Nachteile.

Vorteile

Flexibilität im Layout

Während eine Partitionstabelle immer fix ist und nur unter bestimmten Bedingungen geändert werden kann, ist LVM immer vollständig flexibel. Gehen wir bei Partitionen von folgender Situation aus:

sda1 - 20GB - /
sda2 - 20GB - /usr
sda3 - 20GB - /home

Jetzt fällt einem auf dass man sda1 viel zu großzügig dimensioniert hat, man wird auf diesem Dateisystem niemals an die 20GB Grenze kommen. Also wäre es sinnvoll sda1 auf 10GB zu verkleinern und diesen Platz sda3 zu überlassen, da hier zu erwarten ist dass dort mit der Zeit immer mehr Daten anfallen. Mit Partitionen ist das nicht möglich. Zwar kann man sda1 verkleinern, der freie Platz liegt dann aber zwischen sda1 und sda2. Partitionen müssen immer an einem Stück sein, weswegen es nun nicht möglich ist den übrigen Platz sda3 zuzuweisen. Man könnte ihn nur sda2 überlassen. Es wäre höchstens möglich durch zeitaufwendige und nicht ganz ungefährliche Verschieboperationen das Problem lösen.

LVM hingegen ist egal wo die Bereiche liegen. Ob das nun an einem Stück ist oder nicht ist völlig egal, es kann sogar auf einem völlig anderem Gerät(z.B. einer anderen Festplatte) liegen. Den Benutzer kümmert es meistens auch nicht wo was genau liegt, er kann das System einfach benutzen.

Vergrößern und Verkleinern

Zwar kann man auch Partitionen vergrößern und verkleinern, allerdings beschreibt das obige Beispiel die Restriktionen ganz gut. LVM unterstützt vergrößern und verkleinern im Betrieb, das Ganze dauert keine 5 Sekunden. Es sei allerdings dazu gesagt dass die allermeisten Dateisysteme zwar vergrößern im Betrieb erlauben, verkleinern aber nicht. Ext3 und 4 gehören dazu.

Snapshots

LVM unterstützt sogenannte Snapshots. Dabei wird ein neues Blockdevice angelegt, welches den Zustand des jeweiligen Volumes zu dem Zeitpunkt des Snapshots repräsentiert. Dieses Blockdevice ist auch beschreibbar. So ergeben sich verschiedene Vorteile:

- Es können auf schnellste Art und Weise Backups angelegt werden. Müsste das System für ein konsistentes Backup normalerweise für die gesamte Zeit offline sein, reicht es kurz alles nötige abzuschalten, den Snapshot anzulegen und dann wieder alles zu aktivieren. Man kann dann in aller Ruhe von dem Snapshot ein Backup anlegen, während das System unberührt weiterläuft. Gerade für Server ein unschlagbarer Vorteil.

- Dadurch dass die Snapshots auch beschreibbar sind ist es auch möglich von ihnen zu booten, es sind ja ganz normale Blockdevices. Das ist perfekt falls es sich bei dem betreffenden System um ein Produktivsystem handelt, gerade bei Arch Linux. Arch Linux ist eine "bleeding edge" Distribution, in der immer das Neueste zu finden ist. Daher kann und wird es passieren dass irgendwelche Updates das System in Teilen oder im Ganzen unbenutzbar machen. Ohne Snapshots müsste man sich nun mit dem Problem beschäftigen, wofür im Zweifelsfall keine Zeit ist. Mit Snapshots rebootet man einfach auf sein garantiert funktionierendes System und kann sich mit den Problemen beschäftigen wenn Zeit dafür ist.

Mit den Snapshots von LVM ist allerdings, im Gegensatz zu denen von ZFS, kein Rollback möglich. Man kann LVM also nicht sagen "Vergiss alles was passiert ist und spring zu dem Stand des Snapshots zurück". Benötigt man einen solchen Mechanismus muss man alle Änderungen auf dem Snapshot selbst machen, denn den Snapshot kann man wieder löschen.

Nachteile

Linux exklusiv (nahezu)

LVM gibt es fast ausschließlich für Linux. HP-UX verwendet ihn zwar auch, spielt aber im Privatbereich nahezu keine Rolle. Zwar hat *BSD mit GEOM einen ähnlichen Mechanismus, allerdings ist GEOM nicht mit LVM kompatibel. Für andere Betriebssysteme wie Mac OSX oder Microsoft Windows gilt das gleiche. Daher lohnt es sich nur dann LVM einzusetzen wenn auf dem System exklusiv Linux läuft, man kann von anderen Betriebssystemen die Daten im LVM nicht lesen. Eine Notlösung wäre die Einrichtung einer Ext2/3 oder FAT Austauschpartition, wobei für diese dann wieder die Einschränkungen der Partitionen gelten.

DragonflyBSD unterstützt seit Mitte 2010 LVM (siehe [1]).

Schwerer Umstieg

Man kann Partitionen nicht in LVM Volumes konvertieren, wodurch sich der Umstieg auf einem bereits eingerichteten System als schwer erweist. Man müsste ein neues Volume anlegen und alle Daten dort hin kopieren, was dadurch erschwert wird dass man in einem klassischem System mit Partitionen üblicherweise bereits den gesamten zur Verfügung stehenden Platz durch Partitionen reserviert hat. Entweder man besorgt sich einen weiteren Datenträger mit ausreichender Größe, oder man verkleinert bereits bestehende Partitionen so dass genug Platz vorhanden ist. Man fährt am besten wenn man bereits zur Installation LVM benutzt.

Kompliziertere Benutzung

Durch die vielen Features von LVM muss man sich auch Zeit nehmen um mit LVM umgehen zu können. Der alltägliche und vorallem sinnvolle Umgang mit LVM will gelernt sein.

Keine LVM Unterstützung in GRUB

Dadurch dass in GRUB selbst keine LVM Unterstützung vorhanden ist muss man mindestens eine normale /boot Partition haben auf der GRUB, der Linux Kernel und eine Initrd(falls benötigt) vorhanden sind. Eine Alternative wäre GRUB 2, welches bereits LVM Unterstützung bietet. Allerdings ist GRUB 2 nach wie vor in Entwicklung.

Die Theorie

LVM repräsentiert die Daten ziemlich abstrakt.

Physical Volume

Auf der untersten Ebene sind die sog. Physical Volumes. Das können beliebige Blockdevices sein. Festplatten, Partitionen, Ramdisks und so weiter. Physical Volumes werden weiterhin mit ihren normalen Namen, beispielsweise /dev/sda2, angesprochen.

Volume Group

Physical Volumes werden dann zu Volume Groups zusammengefasst. Diese Volume Groups stellen quasi einen Speicherplatz Pool dar, ähnlich wie eine Festplatte. Allerdings ohne die Begrenzung, dass dieser Pool auf einem bestimmten physikalischen Gerät vorhanden sein muss. Volume Groups werden mit ihrem Namen angesprochen, welchen man selbst wählen kann. Volume Groups dürfen über beliebig viele Physical Volumes verteilt sein und können im Betrieb vergrößert und verkleinert werden. Das Entfernen von Physical Volumes aus einer Volume Group ist logischerweise nur dann möglich wenn sie redundant sind, also die gleichen Daten bereits auf einem anderen Physical Volume vorhanden sind oder sich auf dem zu entfernenden Physical Volume keine Daten befinden.

Logical Volume

In der Volume Group werden wiederrum Logical Volumes angelegt, sie sind ähnlich wie Partitionen. Das sind dann auch tatsächlich die ansprechbaren Blockdevices auf denen sich ein Dateisystem erstellen lässt.

Für ein Logical Volume ist die einzige Begrenzung dass es in einer bestimmten Volume Group sein muss, es kann nicht über 2 verschiedene Volume Groups gehen. Logical Volumes können im Betrieb vergrößert oder verkleinert werden. Logical Volumes können immer angelegt werden solange in der entsprechenden Volume Group genügend Platz vorhanden ist. Sie können weder umbenannt noch entfernt werden sollten sie in Benutzung sein. Logical Volumes werden durch die Volume Group in der sie sich befinden und einen frei wählbaren Logical Volume Namen angesprochen. Ist ein Logical Volume in der Volume Group "tank" und heisst selbst "lvol-root" ist der Pfad zum Blockdevice:

/dev/tank/lvol-root

Es gibt noch einen weiteren Pfad, da der erstgenannte in frühen Bootphasen eventuell noch nicht existiert. Er lautet:

/dev/mapper/tank-lvol--root

Snaphots zählen ebenfalls als Logical Volume, für sie gelten die gleichen Begrenzungen. Zusätzlich müssen sie sich in der selben Volume Group befinden wie ihr Original.

Die Einrichtung

Ich gehe hier von einer frischen Installation mittels einer Arch Linux CD aus, ob x86_64 oder i686 spielt hierbei keine Rolle. Das Arch Linux Setup verfügt zwar über LVM Kompatibilität, allerdings nur so weit dass sich LVM benutzen lässt. Die Einrichtung von LVM muss manuell geschehen. Nachdem man auf eine Konsole gewechselt ist, partitioniert man erstmal normal. Dabei ist nur zu beachten, dass es zwingend eine separate /boot Partition geben muss. Ich empfehle eine Größe von 128-256 MB, damit auch mal ein paar mehr Snapshot Kernel drauf passen. Der Rest kann zu einer Partition allokiert werden und wird dann später in das LVM übernommen. Im Beispiel wird davon ausgegangen, dass /dev/sda1 für /boot verwendet wird, /dev/sda2 und /dev/sdb sollen in das LVM übernommen werden. Nachdem man das Device-Mapper Modul "dm-mod" geladen hat, kann man mittels pvcreate Physical Volumes anlegen:

pvcreate /dev/sda2 /dev/sdb

Nun fügt man diese beiden Physical Volumes mittels vgcreate zu einer Volume Group zusammen:

vgcreate tank /dev/sda2 /dev/sdb

Dabei wird eine Volume Group mit dem Namen "tank" angelegt, welche die beiden Physical Volumes /dev/sda2 und /dev/sdb beinhaltet. In der Volume Group werden jetzt Logical Volumes für die verschiedenen Mountpunkte mittels lvcreate eingerichtet:

lvcreate --name lvol-root -L10G tank

Dies würde das Logical Volume "lvol-root" mit einer Größe von 10 GB in der Volume Group "tank" erstellen. Man möchte natürlich auch Logical Volumes für Swap und /home:

lvcreate --name lvol-swap -L2G tank
lvcreate --name lvol-home -l50%FREE tank

Das erste Kommando arbeitet nach dem selben Prinzip. Im zweiten verwenden wir -l anstatt -L, damit kann man Extents als Größe angeben. 50%FREE gibt an, dass die Hälfte des restlichen Speichers in der Volume Group für lvol-home genutzt werden soll. Ob das schlau ist oder nicht, muss man für sich selbst entscheiden - die Volume Group könnte ja auch 5TB groß sein. Dieses Beispiel soll nur den Syntax zeigen.

Ist das alles geschehen, kann man das Arch Linux Setup starten. Hier überspringt man die Partitionierung und geht direkt zum Festlegen der Mountpunkte. Es sollte sichergestellt sein, dass /dev/sda1 als /boot eingetragen wird, andernfalls wird das System nicht booten. Am Ende der Installation muss man /etc/mkinitcpio.conf bearbeiten, um sicherzustellen, dass "lvm2" in dem HOOKS Array eingetragen ist und vor "filesystems" steht. Es ist zu empfehlen, in /etc/mkinitcpio.conf "dm-snapshot" in das MODULES Array mit einzutragen, da sonst auf kein Volume mehr zugegriffen werden kann sollten Snapshots verwendet werden. Man sollte vor dem Reboot noch sicherstellen, dass Bootloaderkonfiguration und /etc/fstab richtig ausgefüllt wurden, was aber in der Regel der Fall ist.

Der Alltag

Das System läuft zwar jetzt, allerdings haben sich bisher keine Vorteile gegenüber dem klassischen Partitionssystem ergeben. Im Gegenteil, dadurch dass die Einrichtung komplexer war musste man bisher ausschließlich mit Nachteilen leben. Zeit für die Feature Keule.

Mount Punkte setzen

Wie schon erwähnt werden die Mountpunkte mit dem Mapper erstellt. Also ist anstatt /dev/sda2 /dev/mapper/tank-home zu verwenden.

Desweiteren ist unbedingt zu beachten, dass in /etc/mkinitpio.conf die Hooks udev und lvm2 im Hooksarray eingetragen sind und sich lvm2 vor dem filesystems Eintrag befindet.

/etc/mkinitcpio.conf
HOOKS="base udev ... block lvm2 filesystems" 

Partition Hinzufügen

Um eine Partition in die Volume Group aufzunehmen muß diese erst ins 'Linux LVM' Format formatiert werden. Danach wird auf der Platte ein Volumen erstellt und der Volume Group hinzugefügt.

 pvcreate /dev/sdb1
 vgextend tank /dev/sdb1

Partitionen Entfernen

Bevor eine Partition aus der Volume Group entfernt wird, sollten vorher alle Daten auf die restlichen Datenträger der Volume Group geschoben werden, um Datenverlust zu vermeiden.

 pvmove /dev/sdb1

Sollen die daten auf eine bestimmte Festplatte verschoben werden

 pvmove /dev/sdb1 /dev/sda1

Nun kann die Festplatte aus der Volume Group entfernt werden.

 vgreduce tank /dev/sdb1

Weiterhin können alle unbenutzten Festplatten entfernt werden mit

 vgreduce --all vg0

Abschliesend muß nun noch folgender Befehl benutzt werden

 pvremove /dev/sdb1

Vergrößern

Da das Vergrößern von Logical Volumes immer mit ein bisschen Aufwand verbunden ist empfiehlt es sich für alle größeren Sachen ein eigenes Logical Volume anzulegen. Was aber wenn das viel zu klein geraten ist? Mit lvextend können Logical Volumes vergrößert werden, wenn es das Dateisystem erlaubt auch im Betrieb.

lvextend -L15G tank/lvol-home

Würde lvol-home auf 15GB vergrößern. Man kann die Angaben auch relativ machen:

lvextend -L+5G tank/lvol-home

Dies vergrößert lvol-home um 5GB. Man kann ebenfalls -l benutzen um Angaben mit Hilfe von Extents zu machen. Bisher ist nur das Logical Volume vergrößert, das Dateisystem weiß es noch nicht. Im Falle von ext2/3/4 kann man das Dateisystem mit Hilfe von

resize2fs /dev/tank/lvol-home

auf die maximale Größe bringen. Zu beachten ist das hier mit /dev Pfaden gearbeitet werden muss, da resize2fs ja nichts von LVM weiß. Man kann auch in LVM Kommandos mit /dev Pfaden arbeiten.

Verkleinern

Verkleinern funktioniert im Prinzip gleich, allerdings muss hier auf das Dateisystem geachtet werden. Nur die wenigsten unterstützen das Verkleinern im Betrieb, ext2/3/4 gehören nicht dazu. Falls das Dateisystem das Verkleinern im Betrieb nicht unterstützt muss es vorher ausgehangen werden, andernfalls kommt es von Datenverlust bis hin zur Zerstörung des gesamtem Dateisystems. Bevor man das Logical Volume verkleinert muss das Dateisystem verkleinert werden, sonst würde man am Ende Daten abschneiden. Bei ext2/3/4 geht das ebenfalls mit resize2fs:

resize2fs /dev/tank/lvol-home 10000

Würde das Dateisystem auf lvol-home auf etwa 9.8GB verkleinern. Man sollte zuerst das Dateisystem etwas kleiner als die endgültige Größe machen und nachher auf die maximale bringen, damit auch sichergestellt ist dass keine Daten abgeschnitten werden. Nun wird das Logical Volume selbst mittels lvreduce verkleinert:

lvreduce -L10G tank/lvol-home

Auch hier kann wieder mit relativen Angaben und Extents gearbeitet werden. Zum Schluss wird noch das Dateisystem auf die endgültige Größe gebracht:

resize2fs /dev/tank/lvol-home

Snapshots

Snapshots anzulegen ist nicht viel Aufwand. Es muss nur sichergestellt sein dass in der Volume Group genug unreservierter Platz vorhanden ist, da die Änderungen vom Snapshot zum Original und umgekehrt in die Volume Group geschrieben werden. Ein Snapshot kann man mit dem Parameter -s oder --snapshot bei lvcreate anlegen:

lvcreate -s --name lvol-root-testing -L5G tank/lvol-root

Sollten mehr als 5GB Änderungen auf dem Snapshot oder dem Original seit Anlegen des Snapshots geschrieben worden sein springt der Snapshot raus und das dort vorhanden Dateisystem ist aller Wahrscheinlichkeit nach defekt. Das Original ist davon nicht betroffen. Der Snapshot ist jetzt unter /dev/tank/lvol-root-testing ansprechbar. Er lässt sich ganz normal mounten und so weiter. Mit lvremove lässt sich der Snapshot auch wieder entfernen:

lvremove tank/lvol-root-testing

Ein testing System

Eingangs wurde erwähnt dass sich LVM Snapshots eignen um Updates zu testen. Allerdings kommt keine schwarze Magie ins Spiel – wir können nicht sofort vom Snapshot booten wenn er angelegt wurde. Es sind ein paar Vorbereitungen nötig.

Als erstes wird ein Snapshot angelegt und gemountet, ich gehe von /mnt/lvol-root-testing aus. Dort wird ein neuer Ordner namens "boot-real" angelegt und die Datei etc/fstab mittels eines Editors geöffnet. Die Gerätedatei des Wurzelverzeichnisses / wird von /dev/mapper/tank-lvol--root auf /dev/mapper/tank-lvol--root--testig geändert. Der Mountpunkt von /dev/sda1 von /boot auf /boot-real. Zusätzlich wird folgender Eintrag hinzugefügt:

/boot-real/testing                    /boot none bind,rw,noatime 0 0

Dieser bewirkt dass der Ordner /boot-real/testing, welcher erst noch angelegt wird, nach /boot gemountet wird. Das hat den Hintergrund dass ein Kernel Update auf dem Testsystem auch den Kernel von dem normalen System überschreiben würde, da sich beide Systeme dieselbe /boot Partition teilen. Mit diesem Eintrag wird das getrennt. Falls man noch mehr Volumes hat auf denen auf Änderungen auftreten könnten die man im normalen System nicht haben möchte(z.B. /usr, /home, ...) muss von diesen auch ein Snapshot angelegt werden. Die Einträge dieser werden wie die von / in etc/fstab abgeändert. Der Snapshot kann jetzt wieder ausgehangen werden. In /boot wird nun der Ordner testing erstellt, in welchen die Dateien vmlinuz26(der Kernel), kernel26.img(die Initrd) und System.map26 kopiert werden. Nun wird jegedlich ein Eintrag im GRUB benötigt um vom neuen Snapshot auch starten zu können. In /boot/grub/menu.lst sollte sich ein Eintrag befinden, der so ähnlich aussieht:

title Arch Linux
root   (hd0,0)
kernel /vmlinuz26 root=/dev/mapper/tank-lvol--root ro
initrd /kernel26.img

Da weder /dev/tank/lvol-root als /, noch /boot/vmlinuz26 als Kernel und /boot/kernel26.img als Initrd benutzt werden soll wird ein neuer Eintrag mit folgenden Inhalt erstellt:

title Arch Linux testing
root (hd0,0)
kernel /testing/vmlinuz26 root=/dev/mapper/tank-lvol--root--testing ro
initrd /testing/kernel26.img

Einmal gespeichert kann man jetzt in GRUB das neue System auswählen und es booten. Im System sollten alle Mountpunkte überprüft werden bevor die Updates letztendlich eingespielt werden. Auch sollte man die bisher geschehenen Änderungen, einsehbar mit lvdisplay unter "Allocated to snapshot" im Auge behalten und rechtzeitig vergrößern falls benötigt. Steht der Wert bei 100% springt der Snapshot raus und das Dateisystem auf dem Snapshot ist wahrscheinlich defekt.

Tipps für den Alltag

Eine komplette Dokumentation über alle Befehle und Möglichkeiten von LVM würde den Rahmen eines Wiki Artikels sprengen, doch ein paar gute Tipps sind nie fehl am Platz.

Alles in Logical Volumes auslagern

Stellt man fest dass etwas größeres nicht mehr in das aktuelle Logical Volume passt(zum Beispiel ein Spiel o.ä.) sollte man dafür ein neues Logical Volume anlegen anstatt das bestehende zu vergrößern. Das hat den großen Vorteil dass man ein Logical Volume viel leichter wieder entfernen kann als ein bestehendes zu verkleinern. Ausserdem trifft dann die zwar minimale, aber trotzdem vorhanden Fragmentierung des neuen Volumes nicht auf das alte zu.