Systemd: Aus den Wirren des Paketmanagements

„Aus den Wirren der Paketabhängigkeiten im Dschungel von Systemd“ man könnte einen Roman damit betiteln 🙂  Gestern abend, es war mal wieder Serverupdatezeit, flutschte eine Anzeige eines Fedora-Paketes, daß keinen Sinn machte, über den Bildschirm: qrencode-libs

QR Codes auf einem Server?

Ja, wenn man eine Webseite hat, die z.b. QR Codes ausgibt, weil eine HandyApp einen Bestätigungscode haben will, warum nicht. Dummerweise hatte dieser Server genau einen Job und der hatte nichts mit QR Codes zu tun. „Naja,ok, das wird jemand mal irgendwann für was ausprobiert haben… kann weg!“ denkste Dir so.. und dann kommt das Erwachen: „Wieso will dnf jetzt systemd löschen?“

$ sudo dnf erase qrencode-libs
[sudo] Passwort für  ….. :
Fehler:
Problem: The operation would result in removing the following protected packages: systemd

Das kommt so …

Der Systemd hat eine harte Abhängigkeit auf die lib von dem qrencoder :

$ rpm -q -R systemd | grep qrenc
libqrencode.so.3()(64bit)

ganz genau genommen ist es journalctl:

$ ldd /usr/bin/journalctl |grep qrenc
libqrencode.so.3 => /lib64/libqrencode.so.3 (0x00007fef36540000)

„Kann mir bitte einer erklären, wieso journalctl QR CODES bauen können müßte ?????“

Kann ja wohl nur ein Fehler sein 😉   Der Maintainer bei Redhat war da jetzt anderer Meinung:

What do you mean "wrongfully"? It's "rightfullly" linking against qrencode-libs because that functionality is used by journalctl.
While somewhat unfortunate, it's correct.

Steht aber allein da, denn auch bei Manjaro Linux ist das schon mal jemandem vor mir aufgefallen und siehe:

https://forum.manjaro.org/t/systemd-238-51-1-has-picked-up-a-dependency-on-qrencode/43070

Could this be due to a dirty chroot?

$ ldd `which journalctl`
	linux-vdso.so.1 (0x00007fff47fc9000)
	libpthread.so.0 => /usr/lib/libpthread.so.0 (0x00007f55fd82e000)
	libc.so.6 => /usr/lib/libc.so.6 (0x00007f55fd477000)
	libsystemd-shared-238.so => /usr/lib/systemd/libsystemd-shared-238.so (0x00007f55fd027000)
	libqrencode.so.4 => not found

I’m pretty certain journalctl doesn’t need qrencode?

Das sehe ich auch so, trotzdem habe ich mal etwas geforscht und die Ursache gefunden:

journalctl .c

#if HAVE_QRENCODE
/* If this is not an UTF-8 system don’t print any QR codes */
if (is_locale_utf8()) {
fputs(„\nTo transfer the verification key to your phone please scan the QR code below:\n\n“, stderr);
print_qr_code(stderr, seed, seed_size, n, arg_interval, hn, machine);
}
#endif

Jetzt wirds spannend:

Wozu wird das benutzt?

Um, wenn es ein UTF8-System ist UND der Code mit dem QR Support kompiliert wurde, einen Verifikations Schlüssel als QR CODE fürs Handy auszugeben, um mit dem Versiegelungs-Schlüssel abgesicherte Journaleinträge zu prüfen.

Das Verfahren heißt bei Systemd Forward Secure Sealing (FSS).  Keine Ahnung wer das Feature von Journald nutzt. Es klingt jedenfalls nach einer brauchbaren Idee, falls ein Hacker die Einträge manipuliert. Ich bezweifle aber stark, daß der Key dabei per QR Code an ein Handy übermittelt werden muß, statt per SCP an einen anderen Server.

Für diese eine Zeile Code da oben, die kaum jemand jemals einsetzen wird (Bitte Zahlen liefern, wer welche hat), immer noch diese Lib mit sich rumschleppen… was solls, GB sind billig  😉

Systemd : The Revenge of Mariadb III

Ich möchte Euch heute eine kleine Weihnachtsgeschichte erzählen, die sich so im Linux Lande Fedora zugetragen hat. Um diese Geschichte zu verstehen, solltet Ihr Euch in diese Vorgeschichte von Mariadb eingelesen haben. Die Geschichte wird Euch lehren, Euch nicht mit dem SystemD anzulegen, denn er wird Euer Ende sein ..

Also, sprach der Admin …

Es ist mal wieder kurz vor Weihnachten. Der erste Schnee fiel schon auf den Boden, da trug es sich zu, daß ein älteres Fedora-System ein Upgrade brauchte. Also hisste der Admin die Wartungsflagge des Servers und begab sich an die Konsole. „Hmm..“  sprach er zu seinem Monitor, „der Server ist alt, und wir könnten zwei Versionen überspringen, und damit viel Zeit sparen.“ Auf dem Monitor lächelte ihn seine Reflektion erfreut an und so ward dnf beauftragt, die OS-Release um zunächst zwei Stufen anzuheben.

Dnf tat wie ihm befohlen und ackerte um die gewünschten Pakete zu installieren. Nach 20 Minuten, war das Werk getan und der Admin beauftragte den Server sich neu zu starten. Er tat wie befohlen.

Nach dem Reboot, ist vor dem nächsten Reboot

In freudiger Erwartung, loggte sich der Admin wieder auf seinen Server ein. Tomcat lief, Cron lief, die Datenbank… lief.. und so startete der Admin die Post-Reboot Prozeduren, um die neue MariaDB Version zu initialisieren, das PHP zu setupen, die Chroot zu füllen und sich seinem eigentlichen Ziel, dem DNS Server zu widmen.

Nach einiger Zeit sagte sein treuer Freund pstree erstaunt zu Ihm : „Aber oh Herr, siehe. Der PowerDNS will nicht antworten, obwohl er läuft.“ Der Admin war geneigt an einen kleinen Post-Upgrade Bug zu glauben und startete den PowerDNS neu. Aber auch das zeigte keine Wirkung. Der Prozess blieb stumm. Wieder war es pstree, das aufgeregt zu ihm rief:  „Meister, Mariadb läuft gar nicht, wie soll PowerDNS da antworten?“

Und so befahl der Admin dem SystemD MariaDB neu zu starten. Er tat wie ihm geheißen, kehrte aber nicht von seinem Auftrage zurück. Auch nach 5 Minuten, blieb der SystemD auf dem Wege der Arbeit verschollen. Unruhe machte sich beim Admin breit. Wieso kam SystemD nicht von seinem Job zurück? Was konnte ihm nur passiert sein?

Auf der Suche nach dem Timeout

Also fragt der Admin den journald, was denn dem Systemd zugestoßen sein könnte. Aber der journald wußte es nicht. Ihm hatte keiner einen Fehler gemeldet. Unterdessen meldete sich pstree und sagte: „Herr, so freue Dich. MariaDB ist wieder da. Und PowerDNS antwortet auch wieder! “ . Der Admin schaute auf den Monitor und brummte ein „Hmmmm“ vor sich hin, als der Job endlich zurück kam. Aber was war das ? Weder MariaDB noch PowerDNS funktionierten noch.

Ein schnelles „systemctl status mariadb“ zeigte nur einen „Fehler 203/Exited“ an, und meinte es sei per Signal beendet worden. Wieder dieses „hmmm“ , diesmal von Reflex auf dem Monitor. „Danke“, sagte der Admin laut. pstree sprang aufgeregt durch die Konsole, nichts ging mehr, das war zuviel für ihn. „Komm wieder runter Tree, ich starts nochmal“. Aber auch das brachte nur das gleiche Ergebnis.

Der SystemD war, oder?

Dann durchfuhr es den Admin wie einen Blitz: „Das ist das verdammte Prozesslimit vom SystemD! Das wars doch beim letzten mal auch !“ Gesagt, geändert. Kein Erfolg! Der Admin wurde nervös. Tree hatte sich bereits in die weit entfernteste Konsole zurückgezogen. „Wir haben doch damals eine eigene Limit.conf gemacht.. wo war die nochmal .. ach ja, /etc/systemd/system/mariadb.d/ … könnte es sein, daß sich das Servicefile geändert hat und jetzt irgendeinen Timeoutmist macht ? “ murmelte der Admin zu seinem Abbild auf dem Monitor.

Ein kurzes „diff /usr/lib/systemd/system/mariadb.service /etc/systemd/system/mariadb.service “ erhellte die Mine des Admin.. „JA, DAS WARS“. Endlich. Das eigene Unitfile war derart veraltet, weil es für zwei OS Releases früher gemacht war, daß der Systemd einen falschen Weg zum Start einschlagen mußte. Als der Admin das File entfernte und den Dienst startete, sprang Tree jubilierend aus seiner Konsole. Es war geschafft !

Merke, wenn es um MariaDB geht, versteht der SystemD keinen Spaß. Also halte Dich immer an die Anleitung, wenn Du die Limits konform einbauen willst. Außerdem: MariaDB macht immer nur Ärger beim Update ! Aber wieso immer zu Weihnachten ??!?!?! 😀

 

Ein MCP namens SystemD

Bunte Linien kreisen vor meinen Augen und bilden bunte Muster. Die Augen schmerzen. Der Kopf schmerzt und auch das Gehirn hat Schaden genommen. Die Welt ist dunkel, aber bunt.  Ich öffne die Augen. Ein rötlich strahlender Wächter stößt mich mit einer Energielanze an: „Aufstehen, Programm!“ Er will, daß ich mit ihm komme. Wir beschreiten Wege aus Energie… bunter Energie, seltsam neonfarbend und doch schwarz, wie die Nacht. Unterwegs treffen wir andere „Programme“ mit Ihren „Wächtern“. Bald stehe ich vor einem Kopf aus Licht: Der MCP, es gibt ihn wirklich!!!!!!

Verstört wache ich auf. Ein Computeradminalptraum, mitten am Tag, vermutlich am Keyboard eingenickt. Aber was könnte mir so einen Schrecken eingejagt haben, daß ich davon einen Tron .. ähm… traum hatte ?

Es fällt mir wieder ein, ich war grade dabei den Beitrag „Revenge of MariaDB“ Part II zu schreiben. Ja, MariaDB, was war doch gleich … achja.. ging mal wieder nicht nach dem Wechsel von F23 auf F24. Einer unserer Datenbankserver  macht merkwürdige Dinge. Die Webanwendung produzierte sporadisch „Kann nicht in die Datenbank verbinden“ Fehlermeldungen und brachte damit die QA vom Kunden an den Rand des Nervenzusammenbruchs.

Die Analyse geschaltete sich schwierig, weil die Admins immer erst nach einem Vorfall gerufen wurden, aber da ging es wieder. Erst eine zeitnahe Analyse des Netzwerkverkehrs bracht dann den ersten Hinweis: „Can’t create a new Thread. If you have enough free memory, check if … “

Damit konnte man etwas anfangen, ein Blick in eine spezielle Überwachungsdatei brachte dann den Hinweis, daß statt 40.000 Datenbankprozessen, nur wenige Hundert liefen. Also half nur ein Testlauf, mit einer Software, die Verbindungen in die Datenbank aufbaut und offen hält. Sowas kann man schnell in PHP, Perl oder Java schreiben:

import ordb.*;

public class Test {

    public static void main(String[] args) {

        Httpd[] liste = new Httpd[100000];
        for(int i=0;i< Integer.parseInt( args[0] );i++) {
            System.out.println("i="+i);
            liste[i] = new Httpd();
        }
        try {
            Thread.sleep(30000);
        } catch(Exception e) {

            e.printStackTrace();
            System.out.println(e);
        }

    }

}

In einer zweiten Konsole, kann man dann den Datenbankserver überwachen :

strace -e send,read,write -s 1024 -f -p `pidof mysqld`

Damit hat man alle Datenbankserverinstanzen im Blick, was die so Lesen und Schreiben und tatsächlich bestätigte dies den Anfangsverdacht, daß der Datenbankserver nicht genug Prozesse spawnen kann. Er setzte bei 512 Prozessen aus, viel zu wenig für unsere Anwendung.

Der schwierige Teil : Limits prüfen

Als erstes denkt man natürlich, daß sich bei den Limits aus Systemd und die Limits : The Revenge of Mariadb etwas geändert hätte, hatte es aber nicht. Wenn man das OS updatet können aber noch ganz andere Dinge passieren, also muß man hier nach „neuen“ Limits suchen.  Um überhaupt die Limits eines Prozesses Live einsehen zu können, muß man ins /proc/ eintauchen:  cat /proc/`pidof mysqld`/limits

Das kann dann so aussehen:

Limit                     Soft Limit           Hard Limit           Units     
Max cpu time              unlimited            unlimited            seconds   
Max file size             unlimited            unlimited            bytes     
Max data size             unlimited            unlimited            bytes     
Max stack size            unlimited            unlimited            bytes     
Max core file size        unlimited            unlimited            bytes     
Max resident set          unlimited            unlimited            bytes     
Max processes             unlimited            unlimited            processes 
Max open files            65536                65536                files     
Max locked memory         65536                65536                bytes     
Max address space         unlimited            unlimited            bytes     
Max file locks            unlimited            unlimited            locks     
Max pending signals       32195                32195                signals   
Max msgqueue size         819200               819200               bytes     
Max nice priority         0                    0                    
Max realtime priority     0                    0                    
Max realtime timeout      unlimited            unlimited            us

Dummerweise sagt dies genau, was man nicht hören will: Alles ok, es gibt keine Limits bei den Prozessen.

Und jetzt steht man da, wo zum Geier kommt dieses 512 Prozesse Limit her?

Es gibt eine Datei namens:  /etc/security/limits.conf

In der könnte man Limits für User eintragen, was aber nicht der Fall war. Außerdem wäre das in der Auflistung genau dieser Limits aufgefallen. Wo kommt dann das Limit her ?

An der Stelle muß man dann praktisch zu Denken anfangen, weil Docs lesen bringt einen fast nicht weiter, weil man gar nicht damit rechnet, daß es noch mehr Limitmöglichkeiten gibt, also auch nicht weiß in welcher Richtung man suchen sollte. Ein gesunder Pragmatismus ist jetzt hilfreich, vielleicht wars auch eine Verzweiflungstat :  grep -r 512 /etc/ /proc/sys/

Also in allen Dateien von ETC und PROC nach einer EIntragung mit 512 zu suchen. Und genau das hat zum Erfolg geführt, so daß ich jetzt eine Anklage wegen Ruhestörung und einen Abdruck meiner Hand an der Stirn habe 😀

Der SystemD macht mehr als er sollte

Im SystemD gibt es eine Konfigurationsdatei : /etc/systemd/system.conf

Der Auslieferungszustand bei Fedora ist, daß dort alle Werte auskommentiert sind, also ungültig sind. Dort fand sich eine 512 Eintragung und der Name der Option war … DefaultTasksMax=512 !

Aber die Option war abgeschaltet, also ist doch die erste Annahme, daß es kein Limit gibt, oder? Tja, Pech gehabt! Der Wert ist nur Deko, weil als Default in den SystemD einkompiliert 🙁

Zum Glück kann man den Wert in dieser Config ändern, den SystemD + MariaDB neustarten und dann wird der neue, unlimitierte Wert auch übernommen. Er taucht in keiner ( mir bekannten ) Procdatei auf. (Hinweise willkommen)

Alles in allem eine Änderung die wohl zu einer heftigen Reaktion seitens der Betroffenen geführt hat, weil die Systemd Entwickler das in einer neueren Version auf 15% der möglichen Prozesse eines Systems limitiert haben. In  unserem Fall wäre das noch schlimmer gewesen, weil wir so noch schlechter hätten Debuggen können, weil es sehr viel seltener passiert wäre.

Warum gibt es das Limit überhaupt ? Ja, weil es Bomben gibt. Das sind z.b. Bashscripte die sich selbst starten und dabei von der Shell abforken, so daß nach kurzer Zeit alle Resourcen eines Systems aufgebraucht sind. Hackt man also einen Server, könnte man den so intern dosen. Damit das nicht geht, gibt wenigstens ein Limit 😉 Das mal jemand Fedora als Server benutzt und dann auch noch als High Performance, damit hatte wohl niemand gerechnet 😀

Meiner Meinung nach, sollte sich der SystemD auf das Starten von Programmen konzentrieren, denn da ist er bedingt besser als SystemV. Aber die ganzen anderen Anmaßungen die das Teil so vornimmt, sind nicht so schön. Der SystemD kann einen echt fertig machen 😉

Ich bin mal gespannt, was beim nächsten OS Upgrade auf uns wartet 😉