3

I'm currently trying to make a systemd service with two Fifo sockets. These sockets map to stdout and stdin of the application. I'm currently using the following configuration files.

foo.service

[Unit]
Description=foo Fifo test
After=network.target foo-in.socket foo-out.socket
Requires=foo-in.socket foo-out.socket

[Service]
Sockets=foo-out.socket
Sockets=foo-in.socket
StandardOutput=fd:foo-out.socket
StandardInput=fd:foo-in.socket
StandardError=journal
ExecStart=/path/to/foo/exec

foo-out.socket

[Unit]
Description=foo Task Writes to this

[Socket]
Service=foo.service
ListenFIFO=%t/foo/out

foo-in.socket

[Unit]
Description=foo Task reads commands from this

[Socket]
Service=foo.service
ListenFIFO=/run/user/1000/foo/in

I can start the service using the commands systemctl --user daemon-reload and systemctl --user start foo. The problem comes when I try stopping foo.service. I receive this message:

Warning: Stopping foo.service, but it can still be activated by:
  foo-in.socket
  foo-out.socket

Is there a way to stop the sockets automatically when the service is stopped?

1
  • Generally speaking, I avoid directly starting and stopping any service that uses a socket. Instead, I start/stop the socket directly. In your case - with two sockets - you probably want a target that Wants both sockets, which are both PartOf the target. Then you can manage the whole thing using the target, rather than the service. – rich remer Aug 1 '19 at 17:08
0

ExecStopPost Method

You can use the [Service] block's ExecStopPost= option to run arbitrary commands when the service stops either after successful completion or as a result of a failure.

Example

Only the last line has been updated.

[Unit]
Description=foo Fifo test
After=network.target foo-in.socket foo-out.socket
Requires=foo-in.socket foo-out.socket

[Service]
Sockets=foo-out.socket
Sockets=foo-in.socket
StandardOutput=fd:foo-out.socket
StandardInput=fd:foo-in.socket
StandardError=journal
ExecStart=/path/to/foo/exec
ExecStopPost=systemctl --user stop foo-out.socket ; systemctl --user stop foo-in.socket

Source: systemd.service (emphasis mine)

Additional commands that are executed after the service is stopped. This includes cases where the commands configured in ExecStop= were used, where the service does not have any ExecStop= defined, or where the service exited unexpectedly. This argument takes multiple command lines, following the same scheme as described for ExecStart=. Use of these settings is optional. Specifier and environment variable substitution is supported. Note that – unlike ExecStop= – commands specified with this setting are invoked when a service failed to start up correctly and is shut down again.

It is recommended to use this setting for clean-up operations that shall be executed even when the service failed to start up correctly. Commands configured with this setting need to be able to operate even if the service failed starting up half-way and left incompletely initialized data around. As the service's processes have been terminated already when the commands specified with this setting are executed they should not attempt to communicate with them.

Note that all commands that are configured with this setting are invoked with the result code of the service, as well as the main process' exit code and status, set in the $SERVICE_RESULT, $EXIT_CODE and $EXIT_STATUS environment variables, see systemd.exec(5) for details.

Note that the execution of ExecStopPost= is taken into account for the purpose of Before=/After= ordering constraints.

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.