Opensuse 13.1 – Kernelmodule beim Booten statisch laden

Nach einer kompletten Neuinstallation von Opensuse 13.1 auf einem meiner Systeme gab es keinen Eintrag mehr für das automatische, statische Laden von Kernelmodulen beim Booten in YaST's Modul "/etc/sysconfig"-editor". Normalerweise fand sich ein solcher Eintrag unter:

YaST2 >> Editor für /etc/sysconfig >> System >> Kernel >> MODULES_LOADED_ON_BOOT

Unter OS 13.1 fehlt der Punkt MODULES_LOADED_ON_BOOT dagegen einfach. Ich hatte diese Konfigurationsmöglichkeit in der Vergangenheit immer mal wieder benutzt, um bestimmte Module automatisch zur Bootzeit zu laden. Ein Beispiel ist etwa das Module "loop" zur Behandlung von Loop-Devices. Solche Devices brauche ich etwa im Zusammenhang mit Tests von virtuellen Maschinen oder aber um Realcrypt-Container ins Filesystem einzuhängen.

YaST2's "/etc/sysconfig"-Editor-Modul editiert unter "System >> Kernel" über Schlüsselwörter entsprechende Einträge in der Datei "/etc/sysconfig/kernel". Natürlich konnte man diese Datei auch manuell editieren. Unter OS 13.1 findet sich in der Datei selbst kein Bereich mehr zum Schlüsselwort MODULES_LOADED_ON_BOOT.

Dass der Punkt zum Laden von Kernelmodulen unter YaST2 nicht mehr automatisch vorhanden ist, war mir bislang nicht aufgefallen, da ich die meisten meiner Systeme von Opensuse 12.3 aus upgegradet hatte. Offenbar wurden auf den upgegradeten Maschinen die ursprünglich unter MODULES_LOADED_ON_BOOT angegebenen Module aber anstandslos geladen.

Anlass genug, den Änderungen auf den Grund zu gehen.

Korrespondierende Einstellungen konnte man früher übrigens unter Red Hat in der Datei "/etc/rc.modules", unter Arch Linux unter der "/etc/rc.conf" und unter Debian in der "/etc/modules" vornehmen. Wenn sich bewährte sysconfig-Dinge im einstmals überschaubaren, script-getriebenen Boot-Prozess plötzlich verändern oder entfernt werden, liegt der Verdacht nahe, dass das mit Auswirkungen der Einführung von "systemd" zu tun hat.

Tatsächlich ist dem auch in diesem Fall so. Eigentlich logischerweise - ob man systemd nun mag oder nicht .... Immerhin sorgt es nun zwischen den Distributionen, die heute "systemd" einsetzen, für eine gewisse Vereinheitlichung - auch wenn bisherige Einstellmöglichkeiten über bewährte Admin-Tools dadurch wegfallen.

Interessanterweise legte aber der bei einer Internet-Recherche auftauchende Artikel
http://b.agilob.net/opensuse-how-to-install-truecrypt/
nahe, dass das Schlüsselwort MODULES_LOADED_ON_BOOT in der Datei "/etc/sysconfig/kernel" auch von Opensuse 13.1 sehr wohl noch beachtet wird.

Nach einem Blick auf die systemd-bedingten Änderungen diskutiere ich weiter unten daher 3 Wege, um Kernelmodule unter Opensuse 13.1 gezielt zu laden - ohne dies in Grub oder Grub2 zu verankern. Zukunftsträchtig ist wegen "systemd" vermutlich nur der letzte der Wege sein, obwohl gerade das dortige Vorgehen nicht mehr die Möglichkeit bietet, YaST zur Konfiguration heranzuziehen. Ich beschreibe das Vorgehen jeweils am Beispiel des Moduls "loop". Zunächst gehe ich aber auf das statische Laden von Kernelmodulen unter "systemd"-Bedingungen ein.

systemd und das statische Laden von Kernel-Modulen im Boot-Prozess

systemd liegt u.a. die Vorstellung zugrunde, dass der Boot-Prozess letztlich das Bereitstellen von Service-, Socket, Mount und Device-Units für bestimmte Target-Zustände leistet und dabei bestehende Abhängigkeiten auflöst. Im Rahmen dieser Philosophie erwartet man einen relativ freistehenden elementaren Service, der Kernel-Module lädt. Wie das prinzipiell funktioniert beschreiben folgende Artikel:
http://0pointer.de/blog/projects/the-new-configuration-files
https://wiki.archlinux.org/index.php/systemd
https://wiki.archlinux.de/title/Wechsel_von_Sysvinit_zu_systemd
https://wiki.archlinux.de/title/Kernelmodule#Module_beim_Systemstart_automatisch_laden

Wir zitieren aus dem zweiten wiki-Artikel für Arch-Linux:

Alle Module die bisher in der rc.conf bei MODULES=() eingetragen waren müssen jetzt in eine Datei in /etc/modules-load.d/ eingetragen werden.

Unter Opensuse 13.1 gilt das Analoge für diejenigen Module, die bisher in der "/etc/sysconfig/kernel" unter dem Parameter MODULES_LOADED_ON_BOOT eingetragen wurden.

Und weiter aus dem dritten wiki-Arch-Artikel:

Die meisten benötigten Module werden beim Systemstart vom Init System erkannt und automatisch geladen. Es kann allerdings vorkommen, dass einige Module nicht automatisch erkannt werden. Sollen diese dennoch bei jedem Systemstart geladen werden, müssen sie in eine Datei mit der Endung .conf im Verzeichnis /etc/modules-load.d/ eingetragen werden. Der Name der Datei ist frei wählbar, sie muss nur die Endung .conf haben. Zum Beispiel /etc/modules-load.d/my-modules.conf. Die zu ladenden Module werden zeilenweise in diese Datei eingetragen.

Wie systemd konkret mit einem solchen File unter "/etc/modules-load.d/" umgeht, beschreibt konkret die Antwort auf eine entsprechende Frage in folgendem Forum
http://unix.stackexchange.com/questions/71064/automate-modprobe-command-at-boot-time-on-fedora

Weitere Auskünfte geben folgende man-Seiten:

man systemd-modules-load.service
man modules-load.d

Mit eigenen Worten zusammengefasst:

Unter systemd sorgt ein spezieller Service "systemd-modules-load.service" für das gezielte statische Laden von Kernelmodulen. Die Service-Unit "systemd-modules-load.service" wird spätestens vom systemd-Target "sysinit.target" angefordert. Welche Module durch diese spezielle Unit geladen werden, wird u.a. über Dateien der Form "*.conf" unter dem Verzeichnis "/etc/modules-load.d/" gesteuert. In jeder dieser Dateien kann eine Liste von Modulen angegeben werden. Jedes Modul wird in eine separate Zeile eingetragen.

Hingewiesen sei darauf, dass der Service neben den dateien unter "/etc/modules-load.d/"
auch noch Dateien aus anderen Verzeichnissen aufsammelt! Vorgegeben ist das durch die Datei
"/usr/lib/systemd/system/sysinit.target.wants/systemd-modules-load.service":

# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
 
[Unit]
Description=Load Kernel Modules
Documentation=man:systemd-modules-load.service(8) man:modules-load.d(5)
DefaultDependencies=no
Conflicts=shutdown.target
After=systemd-readahead-collect.service systemd-readahead-replay.service
Before=sysinit.target shutdown.target
ConditionCapability=CAP_SYS_MODULE
ConditionPathExists=|/etc/sysconfig/kernel
ConditionDirectoryNotEmpty=|/lib/modules-load.d
ConditionDirectoryNotEmpty=|/usr/lib/modules-load.d
ConditionDirectoryNotEmpty=|/usr/local/lib/modules-load.d
ConditionDirectoryNotEmpty=|/etc/modules-load.d
ConditionDirectoryNotEmpty=|/run/modules-load.d
ConditionKernelCommandLine=|modules-load
ConditionKernelCommandLine=|rd.modules-load
 
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/lib/systemd/systemd-modules-load

Siehe auch:
https://disunitedstates.org/wiki/index.php/Systemd-modules-load.service

Wie man die Module nach Einsatzzwecken in separaten Dateien unter "/etc/modules-load.d/" organisiert, kann man selbst festlegen. Ich habe nicht überprüft, ob eine Nummernvergabe am Anfang des Namens im Stile "nn-name.conf", wie sie unter Opensuse z.B. im Verzeichnis "/etc/modprobe.d/" vorgenommen wird, auch im Verzeichnis "etc/modules-load.d/" wirksam wirkt, um eine Reihenfolge der Abarbeitung zu erzwingen. Wahrscheinlich nicht. Was wiederum zu Problemen führen kann - siehe
http://archlinux.2023198.n4.nabble.com/systemd-fails-to-set-console-font-td4657110.html

Was ist zu tun, wenn dem Modul auch noch Parameter übergeben werden sollen? Hier hat sich eigentlich nicht viel geändert - im zweiten Artikel findet man eine Beschreibung des klassischen Vorgehens, um den geladenen Modulen Parameter zu übergeben. Dazu sind zusätzliche Dateien unter "/etc/modeprobe.d/" anzulegen.

Unter dem Verzeichnis "/etc/modprobe.d" findet man unter OS 13.1 in der Regel denn auch mit hoher Wahrscheinlichkeit einige Beispiele (u.a. für die jeweilie Soundkarte), die zeigen, wie die Übergabe von Parametern funktioniert. Zur Namensgebung und der Bedeutung der spezifischen Ziffern (seit OS 11.2) siehe
http://forums.opensuse.org/showthread.php/419615-11-2-new-modprobe-d-naming-convention
und dort den letzten Beitrag. Oder auch an einem konkreten Beispiel:
http://en.opensuse.org/SDB:Intel-HDA_sound_problems

Unter Opensuse kann man spezifische lokale Parameterübergaben demnach am besten in einer Datei

/etc/modprobe.d/99-local.conf

abhandeln.

Siehe zur Parameterübergabe an die Module aber auch:
https://bbs.archlinux.org/viewtopic.php?id=176942
http://www.opensuse-forum.de/allgemeines/opensuse-installation/8793-gel%C3%B6st-deprecated-config-file/

Wodurch wurde das früher MODULES_LOADED_ON_BOOT in der Datei "/etc/sysconfig/kernel" unter OS 13.1 ersetzt?

Nach dem erarbeiteten Wissen zum Laden von Kernelmodulen über die systemd-Service-Unit "systemd-modules-load.service" liegt es nahe, dass die unter älteren Opensuse-Versionenen vorgebenen Einträge in "/etc/sysconfig/kernel" beim Upgrade auf OS 13.1 in eine Datei unter "/etc/modules-load.d" verschoben wurden. Tatsächlich findet man dort auf meinen upgegradeten Systemen die Datei

/etc/modules-load.d/MODULES_LOADED_ON_BOOT.conf

Die enthält erwartungsgemäß alle ursprünglich mal über YaST vorgebenen statisch zu ladenden Module.

Ich beschreibe nachfolgend nun drei Wege, wie man unter OS 13.1 z.B. das Modul "loop" statisch beim Booten laden kann.

Weg 1 - händischer Eintrag MODULES_LOADED_ON_BOOT in der Datei
"/etc/sysconfig/kernel"

Folgender händischer Eintrag am Ende der Datei "/etc/sysconfig/kernel" führt zum Erfolg :

## Type: string
## Default: ""
#
# Old fashioned way to load kernel modules under OS 13.1
# Added by root, 27.05.2014
MODULES_LOADED_ON_BOOT="loop"

Für die Dateiänderung sind natürlich root-Rechte erforderlich. Beim nächsten Start von OS 13.1 wird das Kernel-Module "loop" tatsächlich geladen.

Netterweise taucht nun auch in YaST's "/etc/sysconfig"-Editor wieder die Möglichkeit zum Editieren des Eintages auf. Ich nehme an, dass Weg 1 z.Z. noch durch nicht bereinigte YaST-Überbleibsel aus vergangenen Zeiten ermöglicht wird. Erweitert oder ändert man übrigens den händisch vorgenommenen Datei-Eintrag mittels YaST's sysconfig-Editor und nicht durch direktes Bearbeiten der Datei, so wird der Eintrag von YaST auch an "mkinitrd" übergeben. Ich weiß nicht, wie man das unterbinden kann. Notwendig ist diese Übergabe nicht; eigentlich sollten über mkinitrd ja nur Module zu beginn des Bootprozesses zum Tragen kommen, die zum Auslesen von Boot-Devices und zum Ansteuern anderer wichtiger Hardware unumgänglich sind.

Weg 2 - Ergänzen der Module unter
YaST2 >> Editor für /etc/sysconfig >> System >> Kernel >> INITRD_MODULES

Bei diesem Weg verankert man das Laden des gewünschten Modules explizit über "mkinitrd" in die initiale Auswertung eines "initramfs" cpio-Archivs des Kernels (im RAM). Ein totaler Overkill - aber möglich. Natürlich könnte man den Abschnitt zu INITRD_MODULES auch direkt in der Datei "/etc/sysconfig/kernel" editieren. Dieser zweite Weg gefällt mir nicht, weil er explizit ein Modul in das "initramfs"-cpio-Archiv des Kernels verlagert, das aus meiner Sicht dort eigentlich wenig zu suchen hat.

Weg 3 - Anlegen einer Datei
"/etc/modules-load.d/MODULES_LOADED_ON_BOOT.conf"
mit einer Zeile zu dem gewünschten Modul

Der Inhalt der Datei "/etc/modules-load.d/MODULES_LOADED_ON_BOOT.conf" ist in unserem Beispiel für das Modul "loop" denkbar simpel:

mytux:~ # echo loop > /etc/modules-load.d/MODULES_LOADED_ON_BOOT.conf
mytux:~ # cat /etc/modules-load.d/MODULES_LOADED_ON_BOOT.conf
loop

Weitere benötigte statische Module ergänzt man durch neue Zeilen pro Modul. Natürlich hätte man die Datei auch "loop.conf" nennen können. Ich finde die auch von Opensuse selbst gewählten Namen aber instruktiv.

Nach dem erneuten Starten des Systems kann man den Status des zugehörigen systemd-Services abfragen mit:

mytux:~ # systemctl status systemd-modules-load.service
systemd-modules-load.service - Load Kernel Modules
Loaded: loaded (/usr/lib/systemd/system/systemd-modules-load.service; static)
Active: active (exited) since Tue 2014-05-27 17:36:06 CEST; 1min 2s ago
Docs: man:systemd-modules-load.service(8)
man:modules-load.d(5)
Process: 353 ExecStart=/usr/lib/systemd/systemd-modules-load (code=exited, status=0/SUCCESS)
Main PID: 353 (code=exited, status=0/SUCCESS)

May 27 17:36:06 mytux systemd[1]: Starting Load Kernel Modules...
May 27 17:36:06 mytux systemd-modules-load[353]: Inserted module 'loop'
May 27 17:36:06 rux systemd[1]: Started Load Kernel Modules.
 
 
mytux:~ # lsmod | grep loop
loop 27985 0
mytux:~ #

Obwohl ich systemd nicht mag, empfehle ich, diesen Weg 3 zum statischen Laden von Kernelmodulen ab Opensuse 13.1 zu gehen. Auch wenn man dann auf eine einfache Konfiguration mit YaST verzichten muss.