Hacking SystemD

Ich baue seit mehr als 10 Jahren eingebettete Linux-Systeme. Das bedeutet, ich habe viel mit sysV style init gearbeitet. Es ist robust und in der Praxis bewährt, hat aber seine Grenzen. Inzwischen gibt es mehrere Projekte, die die Dominanz von sysinit ablösen wollen, wie Upstart und systemd.

Ich arbeite recht viel mit Fedora, baue sowohl nfsroot-Dateisysteme für plattenlose Arbeitsstationen als auch eingebettete Firmware basierend auf Fedora-Repositorien. Fedora ist eine ungewöhnliche Wahl für diese Art von Arbeit; die meisten Leute würden Debian oder Ubuntu wählen.

Fedora ist bereits mit Release 15 auf systemd migriert. Da systemd neu war, habe ich mich entschlossen, zurückhaltend zu sein und nicht alle meine Toolchains auf Fedora 15 zu aktualisieren. Jetzt sind wir bei 17, und die Dinge sehen ziemlich stabil aus. Also wagte ich den Sprung und erstellte ein nfsroot-System mit Fedora 17. Das Endergebnis ist ähnlich wie LTSP5/Meukow – nur dass alle Pakate dank Fedoras Spitzenposition bei Aktualität großartig neu sind.

Die Dokumentation zu systemd ist spärlich, daher hatte ich einige Schwierigkeiten herauszufinden, wie man systemd verschlanken kann. Mit sysinit sind die Dinge einfacher. Man kürzt einfach rc.sysinit, bis es ordentlich und schlank aussieht. Außerdem verwendet man chkconfig, um irrelevante Dienste zu deaktivieren. Und natürlich deaktiviert man selinux. Das Fedora-Team hat einige nützliche Dokumentation zur Optimierung und Verwendung von systemd bereitgestellt. Sie haben auch einen sysVinit to systemd Cheatsheet sowie einen Debugging-Leitfaden. Diese Seiten waren eine große Hilfe.

Als ich zum ersten Mal versuchte, mein nfsroot-Dateisystem zu booten, wollte es nicht booten. Durch Hinzufügen von

systemd.confirm_spawn=true

zur Kernel-Befehlszeile konnte ich jeden Befehl in systemd steuern und herausfinden, welcher abstürzte.

Eine nette Fähigkeit von systemd ist, chkconfig-ähnliche Befehle auf einem chroot-Dateisystem auszuführen, ohne hinein-chrooten zu müssen. Dies ähnelt der --installroot-Funktionalität von yum, die ich verwendet habe, um das Dateisystem überhaupt erst zu erstellen. Um also cron auf dem neu erstellten System zu deaktivieren, gibt man

systemctl --system --root=$TARGET disable crond.service

ein, wobei $TARGET der Pfad zu Ihrem chroot ist.

Es gibt eine Reihe von Diensten, die systemd startet und die mit obigem Befehl nicht deaktiviert werden können. Hyperlinks zu diesen Diensten/Befehlen existieren auch nicht in /etc/systemd. Der einzige Weg, den ich fand, war das Löschen von Symlinks zu diesen Befehlen aus /lib/systemd/system. Einige der Befehle, die ich für ein eingebettetes/Desktop-System als nutzlos empfand, sind:

/lib/systemd/system/sysinit.target.wants/*binfmt*
/lib/systemd/system/sysinit.target.wants/cryptsetup.target
/lib/systemd/system/sysinit.target.wants/dev-hugepages.target
/lib/systemd/system/basic.target.wants/fedora-configure.service
/lib/systemd/system/local-fs.target.wants/fedora-import-state.service
/lib/systemd/system/local-fs.target.wants/fedora-readonly.service
/lib/systemd/system/local-fs.target.wants/fedora-storage-init*.service