Linux und die drei sysctl-Zwillinge
Gestern hatte ich über die Optimierung des Schreibverhaltens auf einen alten USB-Stick berichtet. Offen gelassen hatte ich, wie ich die Konfiguration des virtuellen Hauptspeichers so ändere, dass das einen Reboot überlebt. Sollte ja nicht so schwierig sein.
Wie sich herausstellte, ist es das auch nicht. Allerdings ist es, wie fast immer bei Linux, mit einer Lernkurve verbunden: Ich kann das Problem stupide googeln und irgendeine Anleitung befolgen, die vielleicht funktioniert1. Oder ich kann versuchen, das Problem tatsächlich zu verstehen.
Bereits gestern hatte ich herausgefunden, dass ich die Konfiguration des virtuellen Hauptspeichers mit dem Tool sysctl
anpassen kann. Die Konfigurationsdatei /etc/sysctl.conf
, die ich dazu angelegt hatte, wird beim Start meines Systems allerdings ignoriert. Die Man-Page von sysctl
nennt verschiedene Orte, in denen sysctl
die Konfigurationsparameter liest:
/run/sysctl.d/*.conf
/etc/sysctl.d/*.conf
/usr/local/lib/sysctl.d/*.conf
/usr/lib/sysctl.d/*.conf
/lib/sysctl.d/*.conf
/etc/sysctl.conf
Ich denke zunächst an einen Fehler in dieser Dokumentation, denn die Werte, die ich in /etc/sysctl.conf
eingetragen habe, werden beim Systemstart nicht gelesen. Außerdem weicht der Quellcode von sysctl
ein wenig von der Beschreibung in der Man-Page ab:
const char *dirs[] = {
"/run/sysctl.d",
"/etc/sysctl.d",
"/usr/local/lib/sysctl.d",
"/usr/lib/sysctl.d",
"/lib/sysctl.d",
};
Dann recherchiere ich im Internet, und alles wird kompliziert. sysctl gibt es nämlich nicht nur einmal:
-
Es gibt eine sysctl-Bibliothek im Linux-Kernel, die aber nur noch so aus Gründen da drin ist und eigentlich gar nicht mehr benutzt werden soll.
-
Dann gibt es das sysctl-Tool, das ich in der Kommandozeile mit
sysctl
aufrufen kann und dessen Man-Page und Quellcode ich oben zitiert habe. Dieses Tool ist, wenn ich das richtig verstanden habe, Teil des procps-Projekts. Das Projekt macht eine Art Pseudo-Filesystem verfügbar, das im Dateisystem in/proc
eingeblendet wird und vielfältige Systemparameter zugänglich macht. Hört sich spannend an, lenkt mich aber unnötigerweise vom eigentlichen Thema meiner Recherche ab. -
Schließlich, und hier komme ich der Lösung näher, gibt es sysctl auch noch als Bestandteil von systemd, nämlich als sysctl.c-Bibliothek und als sysctl.d-Dämon. systemd steuert die Prozesse, die ein Linux-System ausführt, und sorgt u.a. beim Systemstart dafür, dass das geordnet passiert. Dafür gibt es systemd-sysctl.service.
Beim Systemstart passiert jedenfalls das, was in der Man-Page von sysctl.d
beschrieben wird:
[..]
/etc/sysctl.d/*.conf
/run/sysctl.d/*.conf
/usr/lib/sysctl.d/*.conf
[..]
At boot, systemd-sysctl.service(8) reads configuration files from the
above directories to configure sysctl(8) kernel parameters.
Jetzt verstehe ich das, glaube ich: Beim Systemstart lädt systemd-sysctl
etwaige Konfigurationsdateien, während ich im laufenden Betrieb mit sysctl
neue Konfigurationen laden kann. Die beiden Tools werden von unterschiedlichen Teams entwickelt und betreut und irgendwie sind die beiden Projekte nicht optimal miteinander vernetzt. /etc/sysctl.d/*.conf
gehört zur Schnittmenge beider Projekte, also verschiebe ich meine Datei sysctl.conf
einfach in dieses Verzeichnis. Schon funktioniert es.
Ach, und welchen Wert ich jetzt für die Speichereinstellung verwende, ist bei der ganzen Verwirrung etwas in den Hintergrund gerückt. Ich bleibe einstweilen bei 15 MB. Das ist vermutlich etwas zu wenig:
Consensus is that setting vm.dirty_ratio to 10% of RAM is a sane value if RAM is say 1 GB (so 10% is 100 MB). But if the machine has much more RAM, say 16 GB (10% is 1.6 GB), the percentage may be out of proportion as it becomes several seconds of writeback on spinning disks. A more sane value in this case is 3 (3% of 16 GB is approximately 491 MB).
Ich beobachte das mal.
-
Diese hier zum Beispiel, die durchaus richtig ist: “From version 207 and 21x, systemd only applies settings from /etc/sysctl.d/.conf and /usr/lib/sysctl.d/.conf. If you had customized /etc/sysctl.conf, you need to rename it as /etc/sysctl.d/99-sysctl.conf. If you had e.g. /etc/sysctl.d/foo, you need to rename it to /etc/sysctl.d/foo.conf.” ↩