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.

  1. 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.”