]> err.no Git - systemd/commit
dbus: register to DBus asynchronously
authorMichal Schmidt <mschmidt@redhat.com>
Sun, 18 Dec 2011 13:58:10 +0000 (14:58 +0100)
committerMichal Schmidt <mschmidt@redhat.com>
Mon, 19 Dec 2011 23:17:14 +0000 (00:17 +0100)
commitcbd37330bcd039587121a767280fc9fee597af6e
treecec5378a756b6fd927433916fbfb26f86cf17b42
parent81c3f1f6aba52ac5e95241b51083b61c7401be44
dbus: register to DBus asynchronously

Chen Jie observed and analyzed a deadlock. Assuming systemd-kmsg-syslogd
is already stopped, but rsyslogd is not started yet:
 1. systemd makes a synchronous call to dbus-daemon.
 2. dbus-daemon wants to write something to syslog.
 3. syslog needs to be started by systemd.
   ... but cannot be, because systemd is waiting in 1.

Solve this by avoiding synchronous D-Bus calls. I had to write an async
bus registration call. Interestingly, D-Bus authors anticipated this, in
documentation to dbus_bus_set_unique_name():
> The only reason to use this function is to re-implement the equivalent
> of dbus_bus_register() yourself. One (probably unusual) reason to do
> that might be to do the bus registration call asynchronously instead
> of synchronously.

Lennart's comments from IRC:
> though I think this doesn't fix the problem in its entirety
> simply because dbus_connection_open_private() itself is still synchronous
> i.e. the connect() call behind it is not async
> I think I listed that issue actually on some D-Bus todo list
> i.e. to make dbus_connection_get() fully async
> but that's going to be hard
> so your patch looks good

So it may not be perfect, but it's clearly an improvement.
I did not manage to reproduce the original deadlock with the patch.
src/dbus.c
src/manager.c
src/manager.h