Ubuntu 12.10 von crypted-bcache-/ booten: Teil 1: bcache zum laufen bekommen

Problemstellung

Alle meine Rechner haben mindestens zwei Festplatten: eine SSD für / und ~, und eine Magnetplatte für…. naja, Filme, mp3s etc. – aber eben ohne eindeutigen Mountpoint. ~/Downloads und /mnt/data liegt bei mir da drinnen, ~/Desktop hatte ich da mal, weil da auch mal große Datenmengen abgeladen werden, ~ will man da nicht komplett drinnen haben wegen der .$configs. Einfach irgendwie problematisch. Als Lösung bietet sich hier Blockcache an.

Arbeitsweise von Blockcaches

bcache und Konsorten sind ein Block-Layer Cache für Linux. Das heisst es legt sich als zusätzliche Schicht über ein/mehrere bestehendes Blockdevices (z.B. Festplatte) und optimiert an dieser Stelle dann ganz gewaltig.

Ziel ist es, die Vorteile einer SSD Festplatte mit denen einer magnetischen zu kombinieren: Kleine bzw. seek-intensive Lesevorgänge werden auf der SSD gecached, zukünftiges Lesen geht dann entsprechend mit SSD-Geschwindigkeit. Filme, Musik und dergleichen, was vorallem sequenziell gelesen wird, bleibt exklusiv auf der Magnetplatte. Außerdem braucht man sich eben keine Gedanken mehr machen was man wo hin speichert/mounted.

Geht eine SSD kaputt, und das tun sie meiner Erfahrung nach sehr viel regelmäßiger als herkömmliche Festplatten, ist das fast egal, man tauscht sie aus, und hat keinen Totalverlust der Daten and dieser Stelle – eine tote Magnetplatte, sofern sie nicht im RAID läuft, geht natürlich mit totalem Datenverlust einher. Da man aber vernünftige Backups hat, ist das ja auch nicht so schlimm.

Wie oben ja schon verlinkt gibt es diverse Implementierungen von solchen Caches, auf die Schnelle hab ich nur diesen Benchmark gefunden und mich dann kurzerhand für bcache entschieden. Die offizielle Doku findet sich im bcache-kernel.

Der Plan

Mein Laptop läuft noch auf einem uralten Ubuntu, und er hat eh eine SSD und eine Magnetplatte. Ziel ist es also, das frische Ubuntu 12.10 von meinem Desktop auf meinen Laptop zu klonen, und dabei noch einen bcache-Layer einzuziehen. Wenn sich das bewährt, wird der Desktop auch entsprechend konfiguriert. Selbstverständlich soll nach wie vor alles verschlüsselt sein. Als Verschlüsselungssystem kommt bei mir seit langem dm-crypt mit LUKS zum Einsatz, das kommt raus wenn man mit der, inzwischen nicht mehr gepflegten, alternative Installations-CD von Ubuntu die gesamte Festplatte verschlüsselt.

Reihenfolge der Layer

In dem angestrebten Szenario müseen die Daten also durch zwei Layer zusätzlich zu einer normalen Ubuntu-Installation, hierfür gibt es zwei Möglichkeiten:

  1. Festplatte | Bcache | Crypt | Filesystem
  2. Festplatte | Crypt | Bcache | Filesystem

Die erstere Version ist sicherlich ein wenig leichter zu implementieren, allerdings sollte der Cryptolayer meines Erachtens nach stets der unterste sein – wer weiss schon was für Metadaten ein auf Performance getrimmter bcache noch auf die Festplatte packt?

Die Umsetzung

  1. Einen Platz suchen wo man ~9GB Platz frei hat
    cd /tmp
  2. Die vom bcache Team bereitgestellten Kernelquellen ziehen – leider gibts keine individuellen Patches, weswegen noch das ein oder andere Problem wie inkompatible Treiber und so dazu kommt.
    git clone http://evilpiepirate.org/git/linux-bcache.git && cd linux-bcache 
  3. Die im aktuellen Kernel verwendeten Einstellungen übernehmen. Die ganzen neuen Optionen hab ich einfach mit „Enter“ im Default belassen. Das geht sicher auch irgendwie eleganter, make-kpkg kümmert sich da ja an sich auch drum…
    make oldconfig
  4. bcache als Modul (oder im Kernel direkt) aktivieren. (Device Drivers  —> Multiple devices driver support (RAID and LVM)  —>    Block device as cache)
    make menuconfig

    oder einfach das entsprechende Setting direkt im .config setzen

     sed -i 's/^CONFIG_BCACHE=.*$/CONFIG_BCACHE=m/' .config
  5. Den neuen Kernel vorbereiten, das sollte die „version.h“ erstellen
    make prepare
  6. Den neuen Kernel bauen
    fakeroot make-kpkg --initrd --append-to-version=-bcache kernel_image kernel_headers
  7. dabei fallen denn im übergeordneten Verzeichnis zwei .deb Pakete raus – eins mit dem Kernel, eins mit den Kernelheadern. Beide werden sogleich installiert:
    sudo dpkg -i /tmp/*bcache*deb
    deb(Reading database ... 266204 files and directories currently installed.)
    Preparing to replace linux-headers-3.7.0-bcache+ 3.7.0-bcache+-10.00.Custom (using linux-headers-3.7.0-bcache+_3.7.0-bcache+-10.00.Custom_amd64.deb) ...
    Unpacking replacement linux-headers-3.7.0-bcache+ ...
    Selecting previously unselected package linux-image-3.7.0-bcache+.
    Unpacking linux-image-3.7.0-bcache+ (from linux-image-3.7.0-bcache+_3.7.0-bcache+-10.00.Custom_amd64.deb) ...
    Done.
    Setting up linux-headers-3.7.0-bcache+ (3.7.0-bcache+-10.00.Custom) ...
    Examining /etc/kernel/header_postinst.d.
    run-parts: executing /etc/kernel/header_postinst.d/dkms 3.7.0-bcache+ /boot/vmlinuz-3.7.0-bcache+
    Error! Bad return status for module build on kernel: 3.7.0-bcache+ (x86_64)
    Consult /var/lib/dkms/fglrx-updates/8.960/build/make.log for more information.
    Error! Bad return status for module build on kernel: 3.7.0-bcache+ (x86_64)
    Consult /var/lib/dkms/virtualbox/4.1.12/build/make.log for more information.
    Setting up linux-image-3.7.0-bcache+ (3.7.0-bcache+-10.00.Custom) ...
    Running depmod.
    Examining /etc/kernel/postinst.d.
    run-parts: executing /etc/kernel/postinst.d/dkms 3.7.0-bcache+ /boot/vmlinuz-3.7.0-bcache+
    Error! Bad return status for module build on kernel: 3.7.0-bcache+ (x86_64)
    Consult /var/lib/dkms/fglrx-updates/8.960/build/make.log for more information.
    Error! Bad return status for module build on kernel: 3.7.0-bcache+ (x86_64)
    Consult /var/lib/dkms/virtualbox/4.1.12/build/make.log for more information.
    run-parts: executing /etc/kernel/postinst.d/initramfs-tools 3.7.0-bcache+ /boot/vmlinuz-3.7.0-bcache+
    update-initramfs: Generating /boot/initrd.img-3.7.0-bcache+
    W: Possible missing firmware /lib/firmware/rtl_nic/rtl8168g-1.fw for module r8169
    W: Possible missing firmware /lib/firmware/rtl_nic/rtl8106e-1.fw for module r8169
    run-parts: executing /etc/kernel/postinst.d/pm-utils 3.7.0-bcache+ /boot/vmlinuz-3.7.0-bcache+
    run-parts: executing /etc/kernel/postinst.d/update-notifier 3.7.0-bcache+ /boot/vmlinuz-3.7.0-bcache+
    run-parts: executing /etc/kernel/postinst.d/zz-update-grub 3.7.0-bcache+ /boot/vmlinuz-3.7.0-bcache+
    Generating grub.cfg ...
    Found background image: .background_cache.png
    Found linux image: /boot/vmlinuz-3.7.0-bcache+
    Found initrd image: /boot/initrd.img-3.7.0-bcache+
    Found linux image: /boot/vmlinuz-3.2.0-31-generic
    Found initrd image: /boot/initrd.img-3.2.0-31-generic
    Found linux image: /boot/vmlinuz-3.2.0-29-generic
    Found initrd image: /boot/initrd.img-3.2.0-29-generic
    Found memtest86+ image: /memtest86+.bin
    Found Microsoft Windows XP Professional on /dev/sda1
    done

Damit gehen aber die Probleme erst richtig los….

Probleme mit dkms

Ich hab bei mir die fglrx-update Pakete installiert, das sind etwas aktuellere Pakete als die einfachen fglrx, aber auch aus dem Standardrepository von Ubuntu. Im Gegensatz zu allen anderen Kerneln, meinte dkms aber bei 3.7-bcache die header von fglrx, also ohne „-update“ verwenden zu müssen. Erst hätt ich dann halt die einfachen fglrx installiert und verwendet, aber nach dem das am Ende auch nicht funktionierte (untrige Patches crashten das System bei der Initialisierung von Xorg) hab ich am Ende die propritären Treiber direkt von AMD installiert:

cd /tmp
wget http://www2.ati.com/drivers/beta/amd-driver-installer-catalyst-12.11-beta11-x86.x86_64.zip
unzip amd-driver-installer-catalyst-12.11-beta11-x86.x86_64.zip
chmod +x amd-driver-installer-catalyst-12.11-beta11-x86.x86_64.run
./amd-driver-installer-catalyst-12.11-beta11-x86.x86_64.run --buildpkg Ubuntu/precise
apt-get remove 'fglrx*'
dpkg -i fglrx*deb

Jetzt funktionierte dkms immer noch nicht – das lag zum einen daran, dass mir „include/linux/version.h“ der -bcache header fehlten, wohl weil ich den oben beschriebenen „make prepare“ nicht ausgeführt hatte.

# dpkg-reconfigure linux-headers-3.7.0-bcache+
 Examining /etc/kernel/header_postinst.d.
 run-parts: executing /etc/kernel/header_postinst.d/dkms 3.7.0-bcache+ /boot/vmlinuz-3.7.0-bcache+
 Error! Bad return status for module build on kernel: 3.7.0-bcache+ (x86_64)
 Consult /var/lib/dkms/fglrx/8.960/build/make.log for more information.
 # cat /var/lib/dkms/fglrx/8.960/build/make.log
 DKMS make.log for fglrx-8.960 for kernel 3.7.0-bcache+ (x86_64)
 Mon Jan  7 02:36:18 CET 2013
 AMD kernel module generator version 2.1
 kernel includes at /lib/modules/3.7.0-bcache+/build/include not found or incomplete file: /lib/modules/3.7.0-bcache+/build/include/linux/version.h

Da fehlt ihm wie gesagt jetzt noch die version.h, wobei man sich die notfalls auch selber stricken kann, die Anleitung dazu steht in jeder include/linux/version.h. Naja, hilft nichts, danach schlägt das bauen mit dkms immer noch fehl.

~# cat /var/lib/dkms/fglrx/8.960/build/make.log
 DKMS make.log for fglrx-8.960 for kernel 3.7.0-bcache+ (x86_64)
 Mon Jan  7 02:49:18 CET 2013
 AMD kernel module generator version 2.1
 doing Makefile based build for kernel 2.6.x and higher
 rm -rf *.c *.h *.o *.ko *.a .??* *.symvers
 make -C /lib/modules/3.7.0-bcache+/build SUBDIRS=/var/lib/dkms/fglrx/8.960/build/2.6.x modules
 make[1]: Entering directory `/usr/src/linux-headers-3.7.0-bcache+'
 CC [M]  /var/lib/dkms/fglrx/8.960/build/2.6.x/firegl_public.o
 /var/lib/dkms/fglrx/8.960/build/2.6.x/firegl_public.c: In function ‘KCL_MEM_VM_MapRegion’:
 /var/lib/dkms/fglrx/8.960/build/2.6.x/firegl_public.c:3716:39: error: ‘VM_RESERVED’ undeclared (first use in this function)
 /var/lib/dkms/fglrx/8.960/build/2.6.x/firegl_public.c:3716:39: note: each undeclared identifier is reported only once for each function it appears in
 make[2]: *** [/var/lib/dkms/fglrx/8.960/build/2.6.x/firegl_public.o] Error 1
 make[1]: *** [_module_/var/lib/dkms/fglrx/8.960/build/2.6.x] Error 2
 make[1]: Leaving directory `/usr/src/linux-headers-3.7.0-bcache+'
 make: *** [kmod_build] Error 2
 build failed with return value 2

unknown identifier… sieht nicht gut aus für den treiber :/

http://lxr.free-electrons.com/ident?v=3.2;i=VM_RESERVED

http://lxr.free-electrons.com/ident?v=3.7;i=VM_RESERVED

Da ist VM_RESERVED nun tatsächlich in linux 3.7 rausgeflogen, es wurde wohl ersetzt durch

VM_DONTEXPAND | VM_DONTDUMP

Debian hat da nen bug dazu, da ist auch ein Patch dabei, den ich einspiele (der hier sieht auch gut aus, vielleicht sogar besser – er räumt mit dem alten identifier gleich komplett auf). Das betrifft nicht nur die Grafiktreiber, sondern auch Virtualbox und mit Sicherheit einige andere propritäre Module.

# patch -p6 /usr/src/fglrx-9.010/firegl_public.c
--- fglrx-driver-12.11~beta11.orig/common/lib/modules/fglrx/build_mod/firegl_public.c   2012-12-03 03:03:45.000000000 +0100
+++ fglrx-driver-12.11~beta11/common/lib/modules/fglrx/build_mod/firegl_public.c        2013-01-05 12:32:40.605448455 +0100
@@ -203,6 +203,11 @@
 #define VM_SHM 0
 #endif

+// VM_RESERVED is replaced with VM_DONTEXPAND | VM_DONTDUMP in Linux 3.7+
+#ifndef VM_RESERVED
+#define VM_RESERVED (VM_DONTEXPAND | VM_DONTDUMP)
+#endif
+
 #ifdef FGL_LINUX253P1_VMA_API
 // Linux 2.5.3-pre1 and compatibles
 #define FGL_VMA_API_TYPE        struct vm_area_struct *
(CTRL-D)
patching file /usr/src/fglrx-9.010/firegl_public.c
Hunk #1 succeeded at 200.

Und schon funktioniert das ganze:

# dpkg-reconfigure linux-headers-3.7.0-bcache+
Examining /etc/kernel/header_postinst.d.
run-parts: executing /etc/kernel/header_postinst.d/dkms 3.7.0-bcache+ /boot/vmlinuz-3.7.0-bcache+

Ein Reboot in den neuen Kernel läd auch endlich den fglrx Treiber ohne das System zu crashen – und weil ich den Betatreiber von AMD genommen hab, werde ich jetzt auch bis in Ewigkeit daran erinnert werden – unten rechts am Bildschirm… [Update: das lässt sich mit einer korrigierten /etc/ati/signature fixen]

photo weil nicht trivial screenshotbar

photo weil nicht trivial screenshotbar

Wer immer nen aktuellen Treiber verwendet hätte das sicherlich gewusst, mir ist das jetzt erstmal egal. Kernel und Module sind jedenfalls gebaut, jetzt geht’s um die Tools.

Zunächst die Sourcen aus dem Repository ziehen, eine fehlende Dependencie nachziehen und zu guter Letzt Paketbauen für faule (bei letzterem drauf achten dass die Version eine Zahl, und kein Wort ist.).

git clone http://evilpiepirate.org/git/bcache-tools.git
sudo apt-get install uuid-dev
sudo checkinstall make install

Damit wären schon mal die Grundlagen geschaffen – ein funktionierendes System mit bcache support – war doch komplizierter als ich erwartet hatte, vorallem wegen der elendigen proprietären Treiber. Das hat aber mit bcache nichts zu tun, sondern eher allgemein mit dem einhergehenden Kernelupdate. Im nächsten Teil wird das ganze noch auf einen Laptop mit bcache’ed+crypted / übertragen.

Dieser Beitrag wurde unter linux, security, ubuntu abgelegt und mit , , , , , verschlagwortet. Setze ein Lesezeichen auf den Permalink.

Hinterlasse einen Kommentar