Open Source im professionellen Einsatz
Linux-Magazin 07/2014

Zacks Kernel-News

1038

Posix-Ärger: Race Conditions bei Datei-Operationen

Michael Kerrisk, Maintainer der Kernel-Manpages, hat ein Problem mit der Posix-Kompatibilität von Linux zur Sprache gebracht. Offenbar führen »read()« , »write()« und ähnliche Systemaufrufe keine atomaren Ein- und Ausgabe-Operationen durch, schreibt er. In seinen Tests hat er festgestellt, dass Schreibvorgänge mit mehreren Threads unterschiedliche Informationen über die Datei-Offsets erhalten und sich daher gegenseitig überschreiben.

Daneben hat Michael Code zum Reproduzieren des Problems eingereicht. Seiner Meinung nach könnte das virtuelle Dateisystem VFS der Schuldige sein. Außerdem holte er aus dem Mailinglistenarchiv bis zu acht Jahre alte Beiträge, die ähnliche Fälle diskutierten. Er schreibt: "Linux hält sich nicht an die Single Unix Specification 3 oder 4 und ist auch nicht konsistent zu anderen Implementierungen wie Free BSD oder Solaris. Ich bin mir sogar sicher, dass Linux schon in frühen Tagen nicht Unix-kompatibel war."

Linus Torvalds räumt ein, der Pointer auf die Fileposition »f_pos« könnte Grund für eine Posix-Verletzung sein. Dabei holt er aus: "Vor langer, langer Zeit übergaben wir den Pointer auf »f_pos« direkt und der Low-Level-Schreibvorgang aktualisierte alles unter dem Semaphor des Inode, und alles war gut."

Dann sei es aber zu allerhand Problemen mit besonderen Dateien gekommen, mit Treibern, die unmittelbar auf »f_pos« zugriffen, sowie zu schlimmen Race Conditions, weil es kein Locking gab. Laut Linus erledigt der Kernel heute die Ein- und Ausgaben atomar, aber der Zugriff auf »f_pos« an sich erfolgt ohne Locking. Linus fragte Al Viro nach einem Lösungsvorschlag, und dieser verlangte zunächst die Posix-Anforderungen an »read()« und »write()« . Michael lieferte das Zitat: "Rufen zwei Threads beide eine dieser Funktionen auf, soll jeder Aufruf entweder alle Auswirkungen des anderen Threads bemerken oder gar keine." Das gelte für eine Menge Systemaufrufe, fügte er an.

Wenige Tage später schickte Linus ein Patch ein, das einen Mutex für »f_pos« verwendet und es so mit Schreibschutz per Locking ausstattet. Er hält diese Lösung für recht einfach und nachvollziehbar. Nur an einem Punkt geriet er sich mit Al Viro ein wenig in die Haare: Linus möchte in seinem Code Registerpaare zurückgeben und hält das für eine gebräuchliche Programmiertechnik. Al dagegen befürchtet, dass einige Architekturen wie Power PC, Mips und ARM das nicht unterstützen.

Der Kernelchef schlug vor, die Power-PC- und ARM-Leute sollten Unterstützung für Struct-Return in GCC integrieren. Es genüge, zu diesem Zweck ein Flag für die Aufrufkonvention hinzuzufügen. Al brachte eine alternative Lösung ein, die Linus schließlich annahm und auch für Greg Kroah-Hartmans stabilen Kernelzweig empfahl. Michael Kerrisk ließ seine Tests laufen und bestätigte, das Problem sei gelöst.

Die Manpage von read() behauptet schlicht, der Linux-Systemaufruf sei Posix-kompatibel. Die Realität sieht etwas komplizierter aus.

Kann warten

Während der Arbeit an Kernel 3.14 schickte der Entwickler Peter Hurley einige Patches ein. Deren Aufgabe war es, frühere Patches zurückzunehmen, die für ein Problem gesorgt hatten. Marcel Holtmann allerdings mochte nicht alle Änderungen anwenden, da sich die Entwicklung schon in der Release-Candidate-Phase befand. Den Rest wollte er für das Merge Window von 3.15 aufheben.

Der Niederländer Sander Eikelenboom bemerkte allerdings rund einen Monat später, dass die Patches gar nicht angewendet worden waren. John Linville reagierte und fragte nach einem Pull Request für die fraglichen Änderungen. Doch Marcel antwortete: "Du hast alle drei Rücknahmen schon in »wireless-next« als Teil einer größeren Änderung an »RFCOMM« von Peter erhalten." Peter bot an, die wichtigsten Reparaturen später per Cherry-Picking in den dann stabilen Kernel 3.14 zu übertragen.

Hier schaltete sich Linus Torvalds ein: "Wir sollten keinen Kernel 3.14 mit bekannten Fehlern veröffentlichen, nur weil der Fix zu groß für die RC-Phase sein soll." Peter wies ihn darauf hin, dass es sich mittlerweile nur noch um eine Warnung handle, nicht um ein Oops oder einen Absturz. Da beschlossen Linus und Sander, die Patches könnten doch warten.

CPU-Events verfolgen

Perf, ein Tool zur Performance-Analyse unter Linux, bilde einige Hardware-Ereignisse der CPU nicht gut ab. Das hat der deutsche Intel-Entwickler Andi Kleen auf der Mailingliste beklagt. Er schreibt, es unterstütze zwar High-Level-Events, aber bei Low-Level-Ereignissen "muss man die Events in Rohform angeben (sehr unpraktisch), alternative Frontends wie Ocperf einsetzen oder die Libpfm patchen".

Andi fährt fort: "Intel-CPUs können sehr große Event-Dateien haben, Haswell hat etwa 336 Core-Events – und noch mehr, wenn man Uncore- und Offcore-Kombinationen hinzunimmt. Das ist zu viel, um es über die Kernelschnittstelle zu beschreiben."

CPU-Hersteller pflegen meist öffentliche Listen der Events, wie Andi Kleen erklärt. Die Oprofile-Entwickler importieren sie gelegentlich in ihren Code, doch leider veralten diese Kopien rasch. Er schickte Code, der automatisch Intels aktuelle Event-Liste für lokale CPUs zur Verwendung mit Perf herunterlädt. Andi pflegt die PMU-Tools unter https://github.com/andikleen/pmu-tools. Dabei steht PMU für die Performance Monitoring Unit, die die Events zählt.

Schönere Stack Dumps

Die Stack Dumps des Kernels sehen furchtbar aus, findet Sasha Levin von Oracle. Insbesondere mit den Kerneladressen, die als Offsets im Hexadezimalformat angezeigt werden, könne niemand etwas anfangen. Daher hat er ein Skript eingereicht, das sie in Quelltextdateien und Zeilennummern übersetzt.

Linus Torvalds merkt an, Sashas Absichten finde er gut. Eines aber macht er klar: "Der Kernel selbst wird nie die Zeilen nummerieren", schreibt Linus. Auch die Hexadezimalzahlen will er verschwinden lassen. Kompiliere man den Kernel mit zufälligen Basisadressen, seien sie ohnehin wertlos.

Daneben gibt der Kernelchef zu bedenken, dass das von Sasha verwendete Tool »addr2line« nicht mit symbolischen Namen klarkomme. Daher müsse man entweder dieses Werkzeug verbessern oder zu »nm« beziehungsweise »gdb« greifen.

Sasha dagegen möchte einfach die Daten aus der »System.map« verwenden. Das findet Linus gut, hält aber die »vmlinux« -Datei für eine bessere Quelle. Er will noch ein wenig am Kernel arbeiten und Sasha an seinem Skript. (Zack Brown/mhu)

Diesen Artikel als PDF kaufen

Express-Kauf als PDF

Umfang: 2 Heftseiten

Preis € 0,99
(inkl. 19% MwSt.)

Linux-Magazin kaufen

Einzelne Ausgabe
 
Abonnements
 
TABLET & SMARTPHONE APPS
Bald erhältlich
Get it on Google Play

Deutschland

comments powered by Disqus

Ausgabe 11/2017

Digitale Ausgabe: Preis € 6,40
(inkl. 19% MwSt.)

Stellenmarkt

Artikelserien und interessante Workshops aus dem Magazin können Sie hier als Bundle erwerben.