Das Rahmenwerk DKMS ordnet für Anwender und Entwickler Module so, dass sie auch nach einem Kernupdate noch laufen. Als Bonus schnürt das Tool sogar Installationspakete für Distributionen.
Ein Update hat das System zerschossen: Plötzlich funktionieren Drucker, Scanner und andere Geräte nicht mehr, da sie eigene Treiber und Module benötigen. Bringt ein aktualisierter Kernel sie nicht von Haus aus mit, ist die betroffene Peripherie erst einmal nutzlos. Bei Linux sind der Kernel und die Module eins zu eins aufeinander abgestimmt. Passen sie nicht zueinander, lassen sich die Treiber nicht laden, geschweige denn verwenden.
Knigge für die Struktur von Modul-Quellcodes
Als Ausweg aus diesem Schlamassel hatte der PC-Hersteller Dell bereits 2003 für eigene Kunden und als Beitrag zur Linux-Entwicklung den Dynamic Kernel Module Support (DKMS) konzipiert [1]. Einmal installiert wird DKMS bei jedem Update des Kernels aktiv. Das Werkzeug kümmert sich um außerhalb des normalen Kernel-Quellcodes gepflegte Treiber: Sobald der Admin die Treiber angemeldet hat, übersetzt und installiert DKMS sie bei jeder Aktualisierung des Kerns.
Dazu müssen jedoch die Treiber- und Kernelmodul-Programmierer DKMS explizit unterstützen. Zum Glück fällt dies Entwicklern leicht, denn es nützt ihnen, dass die Software als Beigabe automatisch Deb- und RPM-Installationspakete baut.
Um den eigenen Quellcode DKMS anzuvertrauen, muss der Entwickler einige Konventionen einhalten und eine Konfigurationsdatei verfassen. So erwartet DKMS den Quellcode eines Moduls in einem Unterverzeichnis von »/usr/src/« . Sein Name setzt sich aus Paket und Versionsnummer zusammen.
DKMS organisiert Module nämlich in Paketen, die eine eindeutige Version haben. Ein Paket darf dabei auch mehrere Module beinhalten. Enthält ein Paket nur ein Modul, legt der Entwickler seinen Quellcode direkt in dem neuen Ordner ab. Ansonsten erhält jedes Modul ein eigenes Unterverzeichnis.
Prominentes Beispiel dafür ist die Virtualisierungslösung Virtual Box: Das Paket nennt sich »vboxhost« und seine Version von Anfang Februar ist »4.0.0« . Damit lautet das Paketverzeichnis »/usr/src/vboxhost-4.0.0/« . Da Virtual Box für den Betrieb den Basistreiber »vboxdrv« , den Treiber für die virtuelle Netzwerkkarte »vboxnetadp« sowie einen für den Netzfilter »vboxnetflt« mitbringt, befinden sich unterhalb des Paketverzeichnisses drei Ordner mit diesen Namen (siehe Abbildung 1).
Pflegehinweise beachten
Auch wenn ein Paket mehrere Module hat, erwartet DKMS pro Paket genau eine Konfigurationsdatei. Sie trägt den Namen »dkms.conf« und befindet sich direkt im Paketverzeichnis. Einstellungen macht der Systemverwalter in Form von Variablenzuweisungen – das als Bash-Skript verfasste Tool verleibt sich die Datei per »source« ein. Die Modulverwaltung erfordert mindestens Angaben zum Paketnamen, zur Version und zu den Modulnamen (siehe Listing 1). Die durch »yes« aktivierte Variable »AUTOINSTALLER« sorgt letztlich dafür, dass DKMS beim nächsten Kernelupdate alle betroffenen Module passend übersetzt und installiert.
Listing 1
Demo-Modul für DKMS
01 /* Dummy-Modul erklärt Funktionsweise von DKMS: */
02 #include <linux/module.h>
03
04 static int __init lm_init(void)
05 {
06 printk("Linux-Magazin Modulinitialisierung\n");
07 return 0;
08 }
09
10 static void __exit lm_exit(void)
11 {
12 printk("Linux-Magazin Deinitialisierung\n");
13 return;
14 }
15
16 module_init(lm_init);
17 module_exit(lm_exit);
18 MODULE_LICENSE("GPL");
Ubuntu kennt das praktische Subsystem in seinem Repository als Paket »dkms« , das ein gleichnamiges Tool installiert. Es beherrscht insgesamt 13 Kommandos, im Alltag benötigen Entwickler und Admins aber nur die acht Befehle aus Abbildung 2 (siehe Kasten “Hinter den Kulissen”). Getreu dem Grundprinzip, Linux möglichst unangetastet zu lassen und Änderungen rückgängig machen zu können, übernimmt DKMS seine zu verwaltenden Module in eine eigene Datenbasis, die es unterhalb von »/var/lib/dkms/« speichert.
Hinter den Kulissen
Ein 4000-Zeilen-Bash-Skript bildet das Rückgrat von DKMS. Es legt Kopien der Originaldateien an, überprüft, ob die Voraussetzungen zum Generieren eines Moduls erfüllt sind, übersetzt es für mehrere Kernelversionen, kopiert das Ergebnis in die zugehörigen Verzeichnisse und lädt das Modul – falls gewünscht – in den aktuell laufenden Betriebssystemkern. DKMS erzeugt auch initiale Ramdisks [2]. Es passt die Konfigurationsdateien für das Laden der Module in »/etc/modprobe.d/« an, falls sie Parameter benötigen oder Anwender sie per Alias ansprechen sollen.
Neben den modulspezifischen Konfigurationen findet DKMS im Ordner »/etc/dkms/« in der Datei »framework.conf« seine globale Konfiguration vor. Zu ihr gehören die Pfade zum Quellcode, wohin das Werkzeug die erzeugten Module speichern soll und wo temporäre Dateien residieren. Sämtliche Konfigurationen, sowohl die modulspezifischen als auch die globalen, bindet DKMS über Shellvariablen ein. Im Verzeichnis »/etc/dkms/« liegen außerdem Template-Dateien, die die Paketierung benötigt. Typischerweise muss der Entwickler sie jedoch nicht anfassen.
Automatisch in die Aktualisierung einbinden
Neben dem eigentlichen Tool »dkms« gehört noch das Skript »dkms_autoinstaller« zum Projekt. Ein Dreizeiler im Verzeichnis »/etc/kernel/postinst.d/« startet es auf einem Ubuntu-System. Das Skript wiederum durchsucht per »find« alle unter »/var/lib/dkms/« liegenden Konfigurationen mit dem Namen »dkms.conf« . Steht in einer der Konfigurationsdateien die Variable »AUTOINSTALL« auf »yes« , ruft der automatische Installateur die Kommandos »dkms build« und »dkms install« auf.
DKMS arbeitet die skizzierten Kommandos nicht plump ab, sondern passt sie je nach Distribution an und kennt dazu RPM-basierte Systeme wie Red Hat, Fedora oder Open Suse genauso wie Debian-Derivate. Ein dediziertes Fehlermanagement sorgt für den reibungslosen Betrieb: Dazu gehört, dass das Tool beispielsweise vorhandene Module gleichen Namens sichert und später bei Bedarf wieder zurückspielt.
Der Aufruf von »dkms add« pflegt ein neues Modul in die Datenbasis ein. Dazu legt das Tool ein Directory für das neue Paket und anschließend ein Unterverzeichnis für die zugehörige Version an. Ein symbolischer Link verweist auf das Quellcode-Verzeichnis mit der Datei »dkms.conf« . Weil es Paketname und Version aufspaltet, verwaltet DKMS übersichtlich mehrere Releases der gleichen Komponente.
Eigene Module hinzufügen
Wer unterhalb des Ordners »/usr/src/« ein neues Verzeichnis mit beispielsweise dem Namen »linuxmagazin-20110113« anlegt und darin den Quellcode eines Moduls (Listing 1), ein passendes Makefile (Listing 2) sowie schließlich die DKMS-Konfiguration (siehe Listing 3 und Kasten “DKMS konfigurieren”) ablegt, kann die Wirkungsweise leicht verfolgen (Abbildung 3). Der Aufruf
Listing 3
Konfigurationsdatei dkms.conf
01 # dkms.conf 02 PACKAGE_NAME="linuxmagazin" 03 PACKAGE_VERSION=20110113 04 AUTOINSTALL=yes 05 06 BUILT_MODULE_NAME[0]="linuxmagazin" 07 08 # Distributionen werten die nachfolgende Variable 09 # in aktuellen Versionen nicht mehr aus. Ubuntu 10 # installiert das Modul unter 11 # /lib/modules/Kernelversion/updates/ 11 DEST_MODULE_LOCATION[0]="/updates"
DKMS konfigurieren
Um ihre Module besser zu ordnen, konfigurieren Systemverwalter DKMS-Pakete durch das Zuweisen von Shellvariablen. Die Datei »dkms.conf« im Hauptverzeichnis des betroffenen Pakets nimmt dank Variablenfeldern auf Wunsch auch Angaben für mehrere Module auf einmal auf, wenn sie alle zu einem Paket gehören. Dann versehen Admins die vorbestimmten Variablen – beginnend bei 0 – mit einer laufenden Nummer. Tabelle 1 stellt die wichtigsten Attribute vor.
Listing 2
Zugehöriges Makefile
01 ifneq ($(KERNELRELEASE),) 02 obj-m := linuxmagazin.o 03 else 04 KDIR := /lib/modules/$(shell uname -r)/build 05 PWD := $(shell pwd) 06 07 default: 08 $(MAKE) -C $(KDIR) M=$(PWD) modules 09 endif 10 11 clean: 12 rm -f *.o *.ko .*.d .*.cmd *.mod.c 13 rm -f modules.order Module.symvers 14 rm -rf .tmp_versions
dkms add -m linuxmagazin -v 20110113
erzeugt den neuen Ordner »/var/lib/dkms/linuxmagazin/« mit dem Namen des Pakets und der Version als Unterverzeichnis »20110113« .
Um das Modul zu erzeugen, ruft der Entwickler das Werkzeug mit »dkms build« und den Optionen »-m« für Modulname sowie »-v« für Version auf:
dkms build -m linuxmagazin -v 20110113
Das Skript kopiert den unter »/usr/src/linuxmagazin-20110113/« liegenden Quellcode ins Verzeichnis »/var/lib/dkms/linuxmagazin/20110113/build/« und ruft dort »make« auf, um die Module zu übersetzen. Der ursprüngliche Quellcode bleibt dabei unverändert. DKMS protokolliert alle Ausgaben des Buildvorgangs in »make.log« , sodass ein Admin später die Ursache von Fehlern erkunden kann. Das fertige Produkt legt DKMS in
/var/lib/dkms/linuxmagazin/20110113/Kernelversion/Kernelarchitektur/module/
ab – repräsentiert durch die Variable »BUILT_MODULE_NAME« in der Konfigurationsdatei »dkms.conf« . Die Installation an die üblichen Stellen für den Produktivbetrieb gibt der Systemverantwortliche durch den Befehl
dkms install -m linuxmagazin -v 20110113
in Auftrag. Das Werkzeug prüft zunächst, ob es bereits ein Modul mit gleichem Namen gibt. Ist das der Fall, überschreibt es das gleichnamige Modul nicht einfach, sondern sichert es zuvor. Entfernt der Systemverwalter ein Modul wieder, kopiert »dkms« den Originalcode zurück. Die Software legt die generierten Module übrigens im Verzeichnis »/lib/modules/Kernelversion/updates/« ab.
Hat er das Modul erfolgreich installiert, lädt es der Anwender mit
modprobe linuxmagazin
in den Kernel. Entwickler freut, dass sie auch Module für einen anderen als den gerade laufenden Kernel erzeugen dürfen. Dazu reicht es, mit der Option »-k« die gewünschte Kernelversion anzugeben – die zugehörigen Header und Konfigurationen müssen auf dem System unter »/usr/src/linux-2.6.x« und »/usr/src/linux-headers-2.6.x-y« installiert sein.
Nach dem erstmaligen Einpflegen übernimmt das Skript »dkms_autoinstaller« die Kontrolle über DKMS. Der distributionsspezifische Updatemechanismus ruft es auf. Der Auto-Installer führt fortan die Subkommandos »build« und »install« in der beschriebenen Weise mit jedem neuen Kernelupdate automatisiert und ohne Benutzerinteraktion aus.
Änderungsschneiderei
Das klappt natürlich nur, solange es keine großen Modifikationen an den verwendeten Kernelschnittstellen gibt. Überarbeitet Linus Torvalds sie jedoch, benötigen Anwender zwangsläufig eine im Quellcode angepasste Version des Moduls. Diese automatisiert im Internet zu suchen und einzuspielen, beherrscht DKMS zurzeit allerdings nicht.
Wer in Handarbeit die aktualisierte und zum neuen Kernel passende Version besorgt hat, deinstalliert oder entfernt zunächst die bisher verwendete Variante. Dazu bietet »dkms« die Kommandos »uninstall« und »remove« an. Remove ist das Gegenstück zu »add« . DKMS löscht damit den kompletten Dateibaum für das Modul unterhalb von »/var/lib/dkms/« , der Code unter »/usr/src/« bleibt erhalten:
dkms remove -m linuxmagazin -v 20110113-k 2.6.32-26-generic
Danach gibt der Admin per »add« die neue Version in die Obhut von DKMS. Die folgenden »build« und »install« generieren und installieren das Modul.
DKMS ist ziemlich flexibel und beherrscht noch deutlich mehr als die dargestellten Basisfunktionen: So lassen sich Modulparameter in den Konfigurationsdateien unterhalb von »/etc/modprobe.d/« ebenso einrichten wie Aliase. Das Werkzeug generiert Module für ganz bestimmte Kernelversionen und legt auf Wunsch eine initiale Ramdisk an. Sind Patches in der Konfiguration aufgeführt, wendet DKMS sie auf den Quellcode an. An wichtigen Stellen im Buildprozess lassen sich außerdem externe Kommandos ausführen.
Alles einpacken
Die Unterkommandos »mkdeb« , »mkdsc« und »mkrpm« erleichtern dem Entwickler die Arbeit erheblich, denn sie schnüren Installationspakete für Debian- und Red-Hat-basierte Linux-Varianten. Dazu braucht der Entwickler im Idealfall nicht einmal etwas zu konfigurieren. Auf dem Rechner benötigt er natürlich die notwendige Software für das Paketebauen, bei Ubuntu beispielsweise das Paket »deb-helper« . Der Aufruf
dkms mkdeb -m linuxmagazin -v 20110113--source-only
erzeugt ein Debian-Paket mit dem Namen »linuxmagazin-dkms_20110113_all.deb« und legt es im Verzeichnis »/var/lib/dkms/linuxmagazin/20110113/deb/« ab (siehe Abbildung 4). Das »all« im Namen bedeutet, dass alle Kernelversionen das Paket akzeptieren. Die Option »source-only« ist nicht unbedingt notwendig, stellt aber sicher, dass nur der Modul-Quellcode, nicht aber das bereits generierte Modul in das Debian-Paket kommt. Dadurch generiert DKMS das Modul auf jeder Plattform neu. Natürlich muss auf jedem Zielsystem ebenfalls das Paket »dkms« installiert sein. Glücklicherweise ist jedes erzeugte Paket bereits von »dkms« abhängig, sodass der Paketmanager automatisch alles Notwendige auf dem Zielsystem installiert.

Abbildung 4: DKMS reicht ein einziges Kommando aus, um beispielsweise ein Debian-Paket zu schnüren. Eine weitere Funktion baut auch RPM-Pakete – praktisch für Modulanbieter, um viele Anwender anzusprechen.
Module ordentlich im Griff
Der Dynamic Kernel Module Support löst das Problem, den Kernel und extern gepflegte Module auf gleichem Stand zu halten. Modul-Anbieter für Nvidia, Virtualbox oder Batman, das Routingprotokoll der Freifunk-Szene, nutzen das Verfahren bereits. Trotzdem ist es bei vielen Entwicklern noch unbekannt. Admins, Anwender und Entwickler profitieren davon, wenn sich das ändert. (mg)
Infos
- Dynamic Kernel Module Support (DKMS): http://linux.dell.com/dkms/
- Eva-Katharina Kunst, Jürgen Quade, “Kern-Technik: Initramfs”, Folge 39: Linux-Magazin 05/08, S. 98








