dbus-broker: dbus activation is not retired in some failure modes

There are cases when dbus activation is not retried when it failed initially. The one I’ve found is when service claims to be started successfully, but terminates before claiming the name on the bus (I believe). In such a case activation->requested remains set to true (verified with gdb) and the service start isn’t retried anymore.

A concrete example:

  1. Create user session without X server running (DISPLAY is not set)
  2. Try to use org.freedesktop.Notifications API (for example call notify-send xxx) - this will request notification daemon in my case mate-notification-daemon, which will exit early due to lack of DISPLAY variable. notify-send xxx will timeout.
  3. Start X server, inject DISPLAY into service activation environment (for example systemctl --user import-environment DISPLAY, if not done automatically)
  4. Try to issue notification again - notify-send xxx will timeout and various debugging techniques confirms the service wasn’t even attempted to be started.

Specific messages from notification daemon:

Aug 08 08:47:19 sys-vpn systemd[654]: Created slice dbus\x2d:1.2\x2dorg.freedesktop.Notifications.slice.
Aug 08 08:47:19 sys-vpn systemd[654]: Started dbus-:1.2-org.freedesktop.Notifications@0.service.
Aug 08 08:47:19 sys-vpn mate-notification-daemon[689]: Unable to init server: Could not connect: Connection refused
Aug 08 08:47:19 sys-vpn mate-notificati[689]: cannot open display: 
Aug 08 08:47:19 sys-vpn systemd[654]: dbus-:1.2-org.freedesktop.Notifications@0.service: Succeeded.

I believe the same will happen if the systemd service initially has some condition not met (for example ConditionPathExists=, that later is met.

By inspecting the source code, I see that activation->requested = false is set only when the service is properly started, or failed to start at all (according to systemd). But there is no handling for the apparently successful startup, but service never appearing on the bus.

For transient systemd units (like in this case) timeout handling could be delegated to systemd by setting Type=dbus and appropriate BusName= (if default would be good). But I think non-transient case should be handled by dbus-broker too.

BTW it worked fine with dbus-daemon.

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 21 (10 by maintainers)

Most upvoted comments

#252 works perfectly for me. No activation problems, no failed units in systemctl --user --type=service

Thanks for confirming! Works for me as well. I will see whether I can prep another release this or next week.