1

I'm learning how to use systemd notify. I'm thinking it is a kind of mechanism, which allows a process to send a notification to another process.

So, I tried to make a notification with the command systemd-notify --ready --status="hello". Then I got an error: No status data could be sent: $NOTIFY_SOCKET was not set. It seems that it needs a listener, just like the socket. But I don't know how to make a listener to receive this notification.

Also, I've known that the service of systemd has some different types, one of them is notify. The doc said, Type=notify: identical to Type=simple, but with the stipulation that the daemon will send a signal to systemd when it is ready.. So it seems that the service whose type is notify can send notification too, but I don't know how to use it either.

1

The systemd-notify tool is specifically meant to be used by a shell that runs as a systemd service using Type=notify.

If you set up a service using Type=notify, systemd will automatically set up a communication socket back to systemd and will export its path to the service under $NOTIFY_SOCKET.

It will also listen for special messages in that socket, such as whether the service is ready (in which case systemd will transition it to status started, since initialization is completed) and also the self-reported status of the service, which will also be reported in the output of systemctl status mytest.service (assuming a service called mytest.)

You can read the man page of systemd-notify for all the details, even though there's a lot of complexity there... Perhaps the example at the end is useful in illustrating how it works.


Let's use that example for a hands-on experiment!

Create a script like the one below somewhere in your system, such as /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

I added some sleep 10s so you can see what's happen, when watching the systemctl status mytest.service output.

Make the script executable:

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

Then create /etc/systemd/system/mytest.service, with contents:

[Unit]
Description=My Test

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

[Install]
WantedBy=multi-user.target

Then reload systemd (so it learns about the unit) and start it:

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

Then watch status output, every so often:

$ systemctl status mytest.service

You'll see it's starting for the first 10 seconds, after which it will be started and its status will be "Waiting for data…".

Now write some data into the FIFO (you'll need to use tee to run it as root):

$ echo somedata | sudo tee /tmp/waldo

And watch the status:

$ systemctl status mytest.service

It will show the status of the service as "Processing somedata" for 10 seconds, then back to "Waiting for data…".

If you were to write this code in C or another language that supports systemd bindings, you would use the sd_notify() function for this purpose. If you're familiar with C, you might want to take a look at the sd_notify(3) man page.

  • So, systemd-notify has to work with fifo file? I mean, we, the users, have to offer a way of communication so that systemd-notify could work? I thought systemd-notify have had some method to build its own way of communication... – Yves Feb 22 at 6:27
  • 1
    @yves No, the fifo has nothing to do with systemd-notify. Filbranden just used it here for the example script to tickle the script somehow from another window. – PerlDuck Feb 22 at 8:35
  • 1
    Yeah the /tmp/waldo fifo is just a very very simple server to illustrate an example. My initial idea of an example was a counter script (set status to $i, increment i, sleep a second, loop.) You can try that too. systemd-notify wants to find the socket back to systemd and that's what gets exported (by systemd) in $NOTIFY_SOCKET, but that's mainly an implementation detail between two parts of systemd itself... I hope that helps you make sense of Type=notify and its uses, that's what this is all about. – filbranden Feb 22 at 11:49
0

Not a complete answer, but I got as far as this, using netcat:

  • in one terminal session, do export NOTIFY_SOCKET=/tmp/test.sock
  • then do nc -l -U -u /tmp/test/sock
  • open another session and do export NOTIFY_SOCKET=/tmp/test.sock
  • systemd-notify --read --status="hello"

This works, but on the netcat side you will get nc: connect: Invalid argument. I don't know how to work around that.

  • How did you create the file /tmp/test.sock? – Yves Feb 22 at 1:10
  • I didn't. It gets created as required. – Jos Feb 22 at 7:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.