Kürzlich bin ich über zwei interessante Features im Zusammenhang mit LVM2 gestoßen…

  • Grub2 kann mit entsprechendem Modul von LVM Partitionen booten, d.h. keine separate /boot Partition nötig.
  • Bei Logical Volumes (LV) auf einer langsamen HDD kann durch bilden eines Cache-Pools mit einer SSD lesen und schreiben beschleunigt werden.

Hier beschreibe ich das Vorgehen und die aufgetretenen Probleme unter Ubuntu 15.04.

GRUB 2 und booten von LVM

Im Beispiel hier wird grub-efi-amd64 verwendet, je nach Variante können sich die Pfade daher etwas unterscheiden. Grub 2 kann im Gegensatz zu seinem Vorgänger von einer ganzen Reihe an Partitionen starten, bzw. Teile nachladen. Eine Übersicht aller Module findet sich in /boot/grub/x86_64-efi. Neben dem hier benötigten lvm.mod finden sich z.B. auch Module zum Starten von mit LUKS verschlüsselten Volumes, ZFS, und diversen Linux Software RAID Konfigurationen.

Migration auf LVM Volume

Zuerst wird das System mit einem Live-Linux der Wahl gebootet. LVM2 Tools sollten mitgeliefert werden oder nachinstallierbar sein.

Die EFI Partition (normalerweise eingehängt in /boot/efi) bleibt unangetastet während der Inhalt der /boot Partition auf das LV das als / eingehängt wird verschoben wird. Idealerweise hängt man im Anschluss gleich die EFI Partition an der richtigen Stelle ein (LV als /newsys eingehängt)

mount /dev/sda1 /newsys/boot/efi

Nun wird der übliche Proc-Mount / Dev-Bindmount / Chroot Tanz gespielt:

mount -t proc proc /newsys/proc
mount -o bind /dev /newsys/dev
mount -o bind /sys /newsys/sys
chroot /newsys

Zuletzt wird die /etc/fstab im chroot aktualisiert, der /boot mount darin entfernt und / auf das LV umgebogen.

Grub anpassen

Unter Ubuntu geschieht dies mehr oder weniger automatisch mit den tools update-grub und grub-install. Vor der ganzen Aktion sieht die /boot/efi/EFI/ubuntu/grub.cfg so aus:

search.fs_uuid 46ef5fb5-4972-497f-bcf5-5a861700c517 root hd1,gpt2
set prefix=($root)'/boot/grub'
configfile $prefix/grub.cfg

Diese Konfiguration wird von grub-install zusammen mit grubx64.efi erzeugt und liegt in der EFI Partition. grubx64.efi enthält nach dem Erzeugen auch alle nötigen Module. Falls man im secure Modus startet auch noch ein signierter, nicht veränderlicher Shim (Details finden sich z.B. in der Ubuntu Doku).

Obige grub.cfg bewirkt, daß eine Variable prefix mit dem /boot Verzeichnis gesetzt wird. Fallback falls nach UUID nichts gefunden wird ist hd1,gpt2. Die eigentliche Konfiguration von GRUB2 erfolgt dann in /boot/grub/grub.cfg, welche durch update-grub erzeugt bzw. aktualisiert wird.

Wenn die fstab aktualisiert ist aktualisieren wir zunächst /boot/grub/grub.cfg mit update-grub, anschließend dann die Bestandteile auf der EFI Partition mit grub-install /dev/sda1.

Die /boot/efi/EFI/ubuntu/grub.cfg sollte nach dem zweiten Schritt ungefähr so aussehen:

search.fs_uuid 64fc64b1-4411-48b1-8aa5-f3c79c730254 root lvmid/KZytrP-VBxB-twlq-rocq-MRJb-79Tl-L1Cz8P/pueBqM-OcV6-dY3a-deAM-XMkh-81A2-fLMy0z
set prefix=($root)'/boot/grub'
configfile $prefix/grub.cfg

Wie man sieht hat sich das setzen der prefix Variablen geändert; es wird nun als hint auf dem LV in einer Volume Group (VG) gesucht. Das format des Hints ist <VG_UUID>/<LV_UUID>, falls man dieses von Hand setzen möchte.

Nun sollte das System direkt vom LV bootbar sein.

LVM Caching mittels einer SSD

Neben den Altbekannten bcache und dm-cache gibt es in aktuellen LVM Releases auch noch LVM Cache. Größter Vorteil der Lösung ist meiner Meinung nach die Flexibilität, die man ja auch von LVM gewohnt ist: Caches können einfach hinzugefügt oder wieder entfernt werden.

Die ausführliche Vorgehensweise ist z.B. hier beschrieben und daher nur kurz Skizziert. Dort finden sich auch Hinweise zur richtigen Wahl der Größe der LVs.

Einrichten des Caches

Nehmen wir an, daß /dev/sda die HDD und /dev/sdb die SSD ist. Auf der HDD findet sich bisher eine LVM Physical Volume (PV) Partition die der Volume group data zugeordnet ist. Das zu cachende LV ist storage, also unter /dev/mapper/data-storage zu finden. Folgende Schritte fügen einen Cache-Pool hinzu:

  • Erweitern der VG auf die SSD, alternativ /dev/sdb1 wenn sdb1 eine PV Partition ist

    vgextend /dev/sdb

  • LV zur Verwaltung der Metadaten, also welche Teile sich im Cache befinden, erstelle

    lvcreate -n storage_cache_meta -L1G data /dev/sdb

  • LV welches als Cache verwendet wird

    lvcreate -n storage_cache -L194G data /dev/sdb

  • Cache LV in einen Cache Pool konvertieren

    lvconvert --type cache-pool --cachemode writethrough --poolmetadata \ data/storage_cache_meta data/storage_cache

  • Cache Pool an zu cachendes LV anhängen

    lvconvert --type cache --cachepool data/storage_cache data/storage

Ein lvs -a sollte jetzt ungefähr so aussehen:

LV                    VG   Attr       LSize   Pool          Origin          Data%  Meta%  Move Log Cpy%Sync Convert
[lvol0_pmspare]       data ewi-------   1,00g
storage               data Cwi-aoC---   2,44t storage_cache [storage_corig]
storage_cache         data Cwi---C--- 194,00g
[storage_cache_cdata] data Cwi-ao---- 194,00g
[storage_cache_cmeta] data ewi-ao----   1,00g
[storage_corig]       data owi-aoC---   2,44t

Gotchas:

  • Reboot: GRUB2 war bei mir nicht zum Booten vom Volume zu überreden. Also /boot oder / doch wieder in eine eigene Partition.
  • Logical Volume Inactive: Nachdem ich das System wieder zum Booten überredet hatte, konnte das Volume nicht aktiviert werden. Dies sollte normalerweise automatisch geschehen, aber auch eine manuelle Aktivierung mit lvchange -a y scheiterte. Grund war das Fehlen von /usr/sbin/cache_check, was unter Ubuntu logischerweise im Paket thin-provisioning-tools versteckt ist. Nach der Installation wird das LV mit Cache ordnungsgemäß aktiviert.

Zusammenfassung:

  • GRUB2 ist wirklich ein Fortschritt. Booten von lvm, luks-Partitionen, … supi. Zusammen mit einem Signierten Bootloader lässt sich sogar ein halbwegs zugenageltes System mit Vollverschlüsselung booten.
  • LVM Caching: Sehr einfach zu konfigurieren und deutlich flexibler als die dm-cache und bcache pendants. Die Kombination mit Booten vom LV hat bei mir leider nicht funktioniert.