Tmpfiles.d
Übersicht
tmpfiles.d ist ein Dienst zur Verwaltung temporärer Dateien und Laufzeitverzeichnisse für Daemons. In dieser Anleitung konzentrieren wir uns hauptsächlich darauf, wie er zum Befüllen von /run und /run/lock verwendet wird. Da /run ein tmpfs-Dateisystem ist, müssen es und sein Inhalt bei jedem Neustart neu erstellt werden. Für Dateien, die dort erstellt werden sollen, sollte dies normalerweise keine Probleme verursachen. Verzeichnisse müssen jedoch oft im Voraus erstellt werden. Dies geschieht am besten mithilfe des tmpfiles.d-Mechanismus.
tmpfiles.d-Konfiguration
Um Verzeichnisse mithilfe des tmpfiles.d-Mechanismus zu erstellen, müssen Sie lediglich eine Datei in %{_tmpfilesdir} ablegen. Sie benötigen die Bauabhängigkeit systemd-rpm-macros, um dieses Makro nutzen zu können.
Benötigt das Paket beispielsweise einige Verzeichnisse in /run, um ausgeführt werden zu können, muss der Paketierer eine Datei namens %{name}.conf erstellen, die als %{_tmpfilesdir}/%{name}.conf installiert wird. Die Datei enthält eine oder mehrere Zeilen in folgendem Format:
d /run/NAME RECHTE BENUTZER GRUPPE -
Die Zeile hat das folgende Format:
-
dgibt an, dass ein Verzeichnis erstellt wird, falls es noch nicht existiert. Bei Bedarf können Sie einen anderen Typbezeichner verwenden. Mögliche Werte finden Sie in der Handbuchseite:man tmpfiles.d. -
/run/NAMEist der zu erzeugende Dateisystempfad. -
RECHTEsind die Zugriffsrechte (im 4-stelligen Oktalformat), die beim Erstellen des Verzeichnisses angewendet werden sollen. -
BENUTZERist der Name des Besitzers des Verzeichnisses. -
GROUPist der Name der Gruppe des Verzeichnisses. -
-gibt an, dass die Verfallsfunktion nicht auf den Inhalt des Verzeichnisses angewendet werden soll. Die Verfallsfunktion dient der automatischen Bereinigung von Dateien, die über einen bestimmten Zeitraum nicht verwendet wurden. Sie ist hauptsächlich für Verzeichnisse wie/tmpnützlich und wird von Paketen selten verwendet. Sie können die Verfallsfunktion gerne verwenden, wenn sie für Ihr Verzeichnis geeignet ist.
Ein Beispiel:
d /run/mysqld 0755 mysql mysql -
Weitere Informationen zu den Optionen finden Sie auf der Manpage zu tmpfiles.d, falls Sie etwas Anspruchsvolleres tun möchten.
Beispiel-Spec-Datei
In der Spec-Datei muss der Paketierer die Konfigurationsdatei tmpfiles.d in das Verzeichnis %{_tmpfilesdir} installieren und sicherstellen, dass das Verzeichnis auch im RPM enthalten ist.
# For the _tmpfilesdir macro.
BuildRequires: systemd-rpm-macros
# tmpfiles.d configuration for the /run directory
Source1: %{name}-tmpfiles.conf
[...]
%install
mkdir -p %{buildroot}%{_tmpfilesdir}
install -m 0644 %{SOURCE1} %{buildroot}%{_tmpfilesdir}/%{name}.conf
# This may not be needed if the upstream's install script creates the directories
# Make sure permissions are correct
install -d -m 0755 %{buildroot}/run/%{name}/
# A bit contrived as most packages will either create a subdirectory or a single file. Not both
# Make sure permissions are correct
touch %{buildroot}/run/%{name}.pid
chmod 0644 %{buildroot}/run/%{name}.pid
[...]
%files
# Use %attr() if needed to change ownership of these two items
%dir /run/%{name}/
%verify(not size mtime md5) /run/%{name}.pid
%{_tmpfilesdir}/%{name}.conf
%{_tmpfilesdir} wird zu %{_prefix}/lib/tmpfiles.d expandiert. Dies ist der Speicherort, an dem die Standard-Skripte des Pakets zur Erstellung temporärer Dateien installiert werden sollen. %{_tmpfilesdir}/%{name}.conf ist nicht als %config-Datei gekennzeichnet, da sie nicht von Administratoren bearbeitet werden soll. Administratoren können die %{name}.conf-Datei des Pakets außer Kraft setzen, indem sie eine gleichnamige Datei in /etc/tmpfiles.d/ ablegen. Dies sollte jedoch nur sehr selten erforderlich sein.
Dateien (nicht Verzeichnisse), die das Programm direkt in /run ablegt, werden im Abschnitt %files als %verify(not size mtime md5) aufgeführt, damit rpm weiß, dass die Datei als Teil dieses Pakets vorhanden sein muss, aber keine Fehlermeldung ausgibt, wenn sich der Dateiinhalt ändert. Dateien in Unterverzeichnissen können auf die gleiche Weise aufgeführt oder ganz weggelassen werden, da diese Dateien bei jedem Neustart gelöscht werden.
Warum nicht einfach die Verzeichnisse mit XXXXXX erstellen?
Es gibt mehrere Möglichkeiten, die Verzeichnisse zu erstellen, aber die meisten haben einen Nachteil, den tmpfiles.d adressiert:
Der Daemon soll das Verzeichnis beim Start erstellen
Daemons laufen oft mit eingeschränkten Benutzerrechten, die keine neuen Verzeichnisse direkt in /run erstellen dürfen. Falls der Daemon seine Rechte nicht abgibt, können Sie ihn so patchen, dass er die Dateien und Verzeichnisse beim Start erstellt, und den Patch anschließend an das Upstream-Projekt senden.
Das Init-Skript soll das Verzeichnis beim Start des Daemons erstellen
Da das Init-Skript von root ausgeführt wird, bevor der Daemon seine Berechtigungen verliert, warum werden die Verzeichnisse nicht dort erstellt?
-
Dieser Code müsste in jedes paketierte Init-Skript implementiert werden. Durch die Verwendung von tmpfiles.d können wir die Anzahl der Stellen, an denen wir solchen Code einfügen müssten, reduzieren.
-
Das Hinzufügen des Befehls
mkdirzu den systemd-Unit-Dateien, wenntmpfiles.dbereits existiert, erfordert die Ausführung von Shellcode für das Init-Skript. Systemd kann den Daemon dann nicht mehr selbstständig starten, was die Ausführung verlangsamt. Der Shellcode führt außerdem imperative Konstrukte in die ansonsten deklarative Struktur ein, was möglichst vermieden werden sollte. -
Die korrekte Benennung der erstellten Verzeichnisse erfolgt automatisch durch den tmpfiles.d-Mechanismus, müsste aber vom Init-Skript manuell durchgeführt werden.
Want to help? Learn how to contribute to Fedora Docs ›