Verwendung von systemd notify

4

Ich lerne, wie man systemd notify benutzt. Ich denke, es ist eine Art Mechanismus, mit dem ein Prozess eine Benachrichtigung an einen anderen Prozess senden kann.

Also habe ich versucht, eine Benachrichtigung mit dem Befehl zu machen systemd-notify --ready --status="hello". Dann bekam ich einen Fehler: No status data could be sent: $NOTIFY_SOCKET was not set. Es scheint, dass es einen Zuhörer braucht, genau wie die Steckdose. Ich weiß aber nicht, wie ich einen Listener dazu bringen soll, diese Benachrichtigung zu erhalten.

Ich habe auch gewusst, dass der Dienst von systemd verschiedene Arten hat, eine davon ist notify. Der Doc sagte Type=notify: identical to Type=simple, but with the stipulation that the daemon will send a signal to systemd when it is ready.. Es scheint also, dass der Dienst, dessen Typ benachrichtigen ist, auch Benachrichtigungen senden kann, aber ich weiß auch nicht, wie ich ihn verwenden soll.

Yves
quelle

Antworten:

4

Das systemd-notifyTool ist speziell für eine Shell gedacht, die als systemd-Dienst ausgeführt wird Type=notify.

Wenn Sie einen Dienst mit Type=notifyeinrichten, richtet systemd automatisch einen Kommunikationssocket wieder auf systemd ein und exportiert seinen Pfad zum Dienst unter $NOTIFY_SOCKET.

Es wartet auch auf spezielle Nachrichten in diesem Socket, z. B. ob der Dienst bereit ist (in diesem Fall wechselt das Systemd nach Abschluss der startedInitialisierung in den Status ), und es wird auch der selbst gemeldete Status des Dienstes gemeldet in der Ausgabe von systemctl status mytest.service(vorausgesetzt, ein Dienst wird aufgerufen mytest.)

Sie können die Manpage vonsystemd-notify für alle Details lesen , obwohl es dort viel Komplexität gibt ... Vielleicht ist das Beispiel am Ende nützlich, um zu veranschaulichen, wie es funktioniert.


Lassen Sie uns dieses Beispiel für ein praktisches Experiment verwenden!

Erstellen Sie ein Skript wie das folgende irgendwo in Ihrem System, wie zum Beispiel /usr/local/bin/mytest.sh:

#!/bin/bash

mkfifo /tmp/waldo
sleep 10
systemd-notify --ready --status="Waiting for data…"

while : ; do
        read a < /tmp/waldo
        systemd-notify --status="Processing $a"

        # Do something with $a …
        sleep 10

        systemd-notify --status="Waiting for data…"
done

Ich habe ein paar sleep 10s hinzugefügt, damit Sie sehen können, was passiert, wenn Sie sich die systemctl status mytest.serviceAusgabe ansehen .

Machen Sie das Skript ausführbar:

$ sudo chmod +x /usr/local/bin/mytest.sh

Dann erstelle /etc/systemd/system/mytest.servicemit Inhalten:

[Unit]
Description=My Test

[Service]
Type=notify
ExecStart=/usr/local/bin/mytest.sh

[Install]
WantedBy=multi-user.target

Laden Sie dann systemd neu (damit es etwas über das Gerät erfährt) und starten Sie es:

$ sudo systemctl daemon-reload
$ sudo systemctl start mytest.service

Dann schauen Sie sich immer wieder die Statusausgabe an:

$ systemctl status mytest.service

Sie werden sehen, dass es startingfür die ersten 10 Sekunden ist, danach wird es sein startedund sein Status wird "Warten auf Daten ..." sein.

Schreiben Sie nun einige Daten in das FIFO (Sie müssen teesie als root ausführen):

$ echo somedata | sudo tee /tmp/waldo

Und beobachten Sie den Status:

$ systemctl status mytest.service

Der Status des Dienstes wird 10 Sekunden lang als "Daten werden verarbeitet" und dann wieder als "Warten auf Daten ..." angezeigt.

Wenn Sie diesen Code in C oder einer anderen Sprache schreiben würden, die systemd-Bindungen unterstützt, würden Sie die sd_notify()Funktion für diesen Zweck verwenden. Wenn Sie mit C vertraut sind, sollten Sie einen Blick auf die Manpage sd_notify (3) werfen .

filbranden
quelle
Also, systemd-notifymuss mit fifoDatei arbeiten? Ich meine, wir, die Benutzer, müssen einen Kommunikationsweg anbieten, der systemd-notifyfunktionieren kann. Ich dachte, systemd-notifyich hätte eine Methode, um eine eigene Art der Kommunikation aufzubauen ...
Yves
2
@yves Nein, das fifohat nichts damit zu tun systemd-notify. Filbranden hat es hier nur für das Beispielskript verwendet, um das Skript aus einem anderen Fenster heraus zu kitzeln .
PerlDuck
1
Ja, das /tmp/waldoFifo ist nur ein sehr sehr einfacher Server, um ein Beispiel zu veranschaulichen. Meine ursprüngliche Idee für ein Beispiel war ein Zählerskript (setze den Status auf $i, inkrementiere i, schlafe eine Sekunde, Schleife.) Das kannst du auch versuchen. systemd-notifymöchte den Socket zurück zu systemd finden und das ist es, was (von systemd) exportiert wird $NOTIFY_SOCKET, aber das ist hauptsächlich ein Implementierungsdetail zwischen zwei Teilen von systemd selbst ... Ich hoffe, das macht Sinn Type=notifyund seine Verwendung, das ist es, was dies ist alles über.
22.
0

Keine vollständige Antwort, aber ich bin so weit gekommen netcat:

  • Tun Sie dies in einer Terminalsitzung export NOTIFY_SOCKET=/tmp/test.sock
  • dann mach nc -l -U -u /tmp/test/sock
  • öffne eine andere Sitzung und mache export NOTIFY_SOCKET=/tmp/test.sock
  • systemd-notify --read --status="hello"

Das funktioniert, aber auf der netcatSeite wirst du bekommen nc: connect: Invalid argument. Ich weiß nicht, wie ich das umgehen soll.

Jos
quelle
Wie haben Sie die Datei erstellt /tmp/test.sock?
Yves
Habe ich nicht. Es wird nach Bedarf erstellt.
Jos