2

Assuming a minimal example like in this question, except for another shell script.

systemfoo@.service:

[Unit]
Description=Foo Service
After=network.target systemfoo.socket
Requires=systemfoo.socket

[Service]
Type=oneshot
ExecStart=/bin/bash /opt/foo/foo.sh
TimeoutStopSec=5

[Install]
WantedBy=multi-user.target

systemfoo.socket

[Unit]
Description=Foo Socket
PartOf=systemfoo@.service

[Socket]
ListenStream=127.0.0.1:7780
Accept=Yes

[Install]
WantedBy=sockets.target

/opt/foo/foo.sh

#!/bin/bash

while true; do
    logger -t FOO "Connection received: $REMOTE_ADDR $REMOTE_PORT"
done

When I connect via

nc 127.0.0.1 7780

the script is invoked correctly. But when I quit nc with CTRL-C, the script runs forever.

Is there a mechanism to send a SIGTERM to the script process, when closing the socket (I assume nc does that when quitting)?

1

No, systemd won't stop the service when the connection is closed.

The reason that is not possible is that, once systemd has accepted a new connection to the socket it's listening on, it will pass that socket to the service started to handle the connection and it will no longer keep any reference to that connection.

In order to detect when the connection was closed by the client, you need to check the socket from the service itself, by reading from stdin or by polling it to check whether it was closed.

2
  • The connection is coming from an INET socket while the process communicates via stdin and stdout. I thought there is some kind of systemd-managed proxy in between. So systemd has control over the socket.
    – gerion
    Jun 6 '19 at 8:01
  • @gerion No, there's no proxy. Stdin and stdout of the process forked by systemd are simply opened (using dup() syscall) to copies of the file descriptor of the socket that was just accepted. But once systemd forks the service process, it closes its own copy of that file descriptor. None if this is really new, inetd would do the same, fork a process to handle an accepted connection, mapping the socket to stdin+stdout of the forked process. systemd doesn't keep any reference to the connection socket.
    – filbranden
    Jun 6 '19 at 11:32

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.