[systemd-devel] dbus and exit-on-idle

Lennart Poettering lennart at poettering.net
Mon May 22 08:36:27 UTC 2017


On Mon, 22.05.17 02:26, Matthijs van Duin (matthijsvanduin at gmail.com) wrote:

> I've been pondering how to allow my bus-activated service to exit when
> it's unneeded (which is 99% of the time), and in particular how to deal
> with exit/activate races correctly...
> 
> In the systemd sources I stumbled across the helper function
> bus_event_loop_with_idle() which does a clever trick by
>  - using sd_notify("STOPPING=1") to make sure systemd will queue any
>    activations from here on
>  - releasing the dbus service name
>  - handling any remaining requests until the name deregistration is
>    confirmed by the dbus daemon
> 
> Thus, any incoming request will either be delivered to you, or trigger a
> new activation and be delivered to the next instance of your service.
> 
> I see two problems here:
>  1. sd_notify is asynchronous and nothing is done to ensure systemd has
>     acted on it before the service name is released.
>  2. If you get an incoming request that requires you to continue running
>     after you've told systemd you're stopping, you're screwed.
> 
> The first problem could be solved by monitoring your own unit status I
> suppose, although it would be more elegant if the sd_notify() could be
> replaced by a dbus call.
> 
> The second problem is more annoying... although you could just register
> your bus name again (which presumably suffices to get any queued calls
> delivered to you?), once you've told systemd you're stopping there's no
> way back currently, and it will SIGKILL you if you take too long.
> 
> Could this be solved by simply allowing a stopping service to change its
> mind, e.g. with sd_notify("STOPPING=0") or perhaps another READY=1 ?

Yes, the exit-on-idle logic on dbus is impossible to implement
correctly for non-trivial cases right now. It's a pity. I think the
best option to solve this properly would be to switch to
AF_UNIX/SOCK_SEQPACKET sockets for this, as an alternate transport,
then do away with all the auth/nego logic and permit assigning names
to such bus connects as part of systemd itself. That way we'd have
unified all connection state logic in a single socket, and could do
dbus activation the same way as normal socket activation and the whole
race problem goes away... 

But of course, that's a lot of work, and would require non-trivial
additions to the dbus spec.

In the meantime, adding a way to "cancel" stopping sounds OK to me.

Lennart

-- 
Lennart Poettering, Red Hat


More information about the systemd-devel mailing list