Auf unseren Premium-Servern hatten wir Anfang des Jahres wirklich heftige Probleme mit ständigen Abstürzen, die sich nicht erklären ließen. Aus heiterem Himmel fingen die Server an, sich immer wieder komplett aufzuhängen, ganz offensichtlich wegen Problemen mit IO. Der Verdacht fiel auf die RAID-Controller von Adaptec, und wochenlang haben wir alle möglichen Probleme analysiert, die sich im Internet dazu finden ließen, Workarounds ausprobiert und sogar mit Energiespareinstellungen experimentiert, es half alles nichts. Und das merkwürdigste: Wochen vorher gab es diese Probleme noch gar nicht. Wenn vorher die Server hunderte Tage problemlos liefen, schaffte es nun kaum eins der Systeme, mal 30 Tage am Stück durchzuhalten, teilweise nur wenige Tage. Im Support wurde das immer peinlicher, es war unmöglich eine Aussage zu Ursache und Behebung zu machen und es musste dringend eine Lösung her.

Also wurde ein Testsystem abgestellt, aber auf dem ließen sich die Fehler nicht reproduzieren. Erst auf einem zweiten Testsystem, diesmal ohne RAID-Controller, kam durch Zufall ein relativ zuverlässiger Test zustande (ein Mischung aus fio und dd), wie das Problem nachzustellen war. Und dann war auch klar: es kann nicht der Controller sein. Es war ein Deadlock im Linux-KernelModul bcache. Nach ein paar Minuten IO-Last hing sich das System einfach auf, und zwar dann, wenn es Daten von einer Cache-SSD auf eine HDD geschrieben hat, während die Geschwindigkeit, mit der das passieren soll, im gleiche Moment neu berechnet wurde.

Mit dem zuständigen Kernel Maintainer ließen sich dann zwei potenzielle Quellen für das Problem finden, und mit ein bisschen Feintuning an Kernel-Parametern konnte ich das Problem auf eine der beiden Stellen eingrenzen. Zum Glück war es möglich, das Problem (auf Kosten der Schreib-Performance) durch weiteres Tuning dieser Parameter abzustellen. Ich habe mir dann lang und breit erklären lassen (müssen), was der Code zu welchem Zweck tut, und der Fix war unfassbar simpel: eine Sperre (genauer gesagt eine reader/writer semaphore), die eigentlich komplett unnötig war und nur „weil man ja nie weiß“ vorhanden war, produzierte das Problem. Zwei Zeilen Code gelöscht, Kernel kompiliert, und schon war das Problem auf dem Test-System, auch nach Tagen von IO-Volllast, verschwunden.

Kurz darauf hatte ich schon geplante Wartungsarbeiten angesetzt, so dass der gepatchte Kernel zumindest auf einigen Systemen produktiv gehen konnte, und siehe da: keine Abstürze mehr. Adaptec (die RAID-Controller) war also doch nicht schuld, der Kernel war es! Warum allerdings das Problem seit kurzem so häufig auftrat und vorher nicht, das bleibt ein Rätsel.

Und so kommt es, dass ich demnächst meinen ersten – und ehrlich gesagt ziemlich kurzen, da er nur zwei Zeilen löscht – Patch für den Linux-Kernel einreichen kann. Und zumindest für mich ist es schon ein kleiner Ritterschlag, dass mein Code (oder mein Entfernen von Code) in den Kernel aufgenommen wird und auch noch so ein ekeliges Problem löst. Wäre das Problem nicht wirklich unangenehm gewesen und hätte mir unzählige schlaflose Nächste bereitet hätte zumindest die Jagd nach dem Fehler fast Spaß gemacht, denn in manchen Informatikern steckt einfach ein kleiner Sherlock Holmes, der erst dann zufrieden ist, wenn er den Fall löst. Und das ist bei mir definitiv der Fall 😉

Und der hilfreiche Kernel Maintainer bekommt zum Dank – er erwähnte eine spezielle Scotch-Sorte, die er gerne trinkt – ein Paket nach Alaska geschickt. Denn dort (für mich ist dort in etwa das Ende der Welt) hat man scheinbar viel Zeit, um das wie, was und warum von  Linux-Kernel-Code zu erklären, und dafür möchte ich mich gerne bedanken!