[systemd-devel] Interactive socket activated service?

Dmitry Golubovsky golubovsky at gmail.com
Thu Oct 11 06:18:16 PDT 2012


Hi,

I am trying to implement a systemd service which provides a sort of
REPL (read-evall-print loop) to local clients connecting to its
control socket; at the simplest it would be "socat readline
/path/to/socket").
A socket is preferred because the service may obtain credentials from
the caller to implement some access control.

The .socket file looks like this:

1 [Unit]
2 Description=some interactive service socket
3
4 [Socket]
5 ListenStream=/path/to/socket
6 Accept=false
7 PassCredentials=true
8 ReceiveBuffer=4096
9 SendBuffer=4096

The .service file looks like this:

1 # Socket activated interactive service
2
3 [Unit]
4 Description=Socket activated interactive service
5 Requires=/path/to/socket
6 DefaultDependencies=no
7 After=sysinit.target
8
9 [Service]
10 Type=simple
11 RemainAfterExit=no
12 ExecStart=/interactive/service/shell/script
13 StandardInput=socket
14 StandardOutput=socket
15 StandardError=journal
16 MountFlags=slave

The service is for now a simple shell script which just echoes
whatever it receives, that is:

1 #! /bin/sh
2
3 # A Socket-driven interactive service.
4 # The service is run upon reception of a command on its socket.
5 # It reads the command form the standard input and replies to the
standard output.
6
7 echo Hello
8
9 while true ; do
10 	read
11 	echo $REPLY
12 done

It does not work. The socket is being created when systemd starts it,
and upon the first connection to the socket the service script is
started. But when the script tries to write a reply to its stdout it
gets ENOTCONN  (transport endpoint is not connected). and I see no
output coming from the script.

I tried to replace socket with pipe (ListenFIFO) and it works as
expected (echoes the input).

I also tried to hook the same script up to a socket using socat:

socat unix-listen:/another/socket system:/interactive/service/shell/script

and it works fine when I do

socat readline /another/socket

input is echoed.

Am I doing anything wrong here, or is there any difference between how
systemd and socat connect sockets to their slave processes (I haven't
looked at the source yet)? Should I have an additional wrapper between
the shell and the socket?

Inspection of /proc/XXX/fd shows that in both socat and systemd cases
the service process' handles 0 and 1 are connected to the same socket,
so no wrapper there.

Thanks.

PS I tried to define my service as a regular one, and put socat
listening on the socket as the service main program; it kinda works,
but I would be happier having normal systemd mechanism working.

-- 
Dmitry Golubovsky

Anywhere on the Web


More information about the systemd-devel mailing list