Comment 11 for bug 1438612

Revision history for this message
In , Martin Pitt (pitti) wrote :

Downstream in Ubuntu we have gotten several reports of shutdown hangs due to remote file systems trying to unmount when the wifi is already down, and simlar issues. In journals [1][2][3] you see things like

systemd[1]: Stopping D-Bus System Message Bus...
avahi-daemon[694]: Disconnected from D-Bus, exiting.
whoopsie[685]: g_dbus_connection_real_closed: Remote peer vanished with error: Underlying GIOStream returned 0 bytes on an async read (g-io-error-quark, 0). Exiting.
NetworkManager[689]: g_dbus_connection_real_closed: Remote peer vanished with error: Underlying GIOStream returned 0 bytes on an async read (g-io-error-quark, 0). Exiting.
wpa_supplicant[1246]: wlan0: CTRL-EVENT-DISCONNECTED bssid=00:0f:66:57:07:7c reason=3 locally_generated=1
NetworkManager[689]: <info> (wlan0): roamed from BSSID 00:0F:66:57:07:7C (RedKite) to (none) ((none))
kernel: CIFS VFS: Server 192.168.1.93 has not responded in 120 seconds. Reconnecting...
systemd[1]: Unmounted <some remote file system path> → this is usually timing out as the network is not reachable any more
Stopped target Remote File Systems.
systemd[1]: Stopping Remote File Systems.
systemd[1]: Stopped target Remote File Systems (Pre).
systemd[1]: Stopping Remote File Systems (Pre).
systemd[1]: Stopping Network Manager...
systemd[1]: Stopped Network Manager.
systemd[1]: Stopping D-Bus System Message Bus Socket.

The main problem is that there is nothing that prevents D-Bus from stopping very early, way earlier than all of the Type=dbus services. There is an attempt to prevent that as systemd implies "After=dbus.socket" for Type=dbus units, but that doesn't save us: you can't re-start D-Bus after shutting it down and expect things to just work, as it loses all of its state. And even if that would work, it's rather pointless (and slow) to try and shut it down early just to have it reactivate several times during shutdown. So in short, I think dbus.socket doesn't really help us with anything except not having to specify precise startup requirements; but we still need them for shutdown.

So what we really need is some way to say "Don't stop dbus.service before any D-Bus client" (i. e. *.service of Type=dbus). We could make dbus.service start before basic.target and stop after basic.target and add DefaultDependencies=no, so that it stops after most stuff; or change the implied After=dbus.socket in systemd to After=dbus.service. But that would also be prone to causing cyclic dependencies, if you e. g. have /var on NFS and need it to start dbus. (I didn't test that, it's just a gut feeling as remote file systems that you need to boot are notoriously susceptible to dependency loops.)

Michael Biebl came up with a crazy, but neat idea for a workaround:

  ExecStop=/bin/true
  KillMode=none

i. e. don't actually stop dbus through the unit, and just let it get killed at the bitter end. But on second thought it's actually quite tempting: Stopping/restarting D-Bus during runtime has never been supported, and always caused your desktop session and half of your services to get killed, so in the distro we went out of our way to prevent maintainer scripts etc. from doing that. So it's at least a nice initial hack which isn't introducing dependency loops. But I figure we should at least discuss a cleaner solution.

Of course this will all be obsolete with kdbus, as then dbus always works. (Incidentally, not ever stopping it gets us rather close in that regard :-) ).

[1] https://launchpadlibrarian.net/201680859/journal.txt
[2] http://paste.ubuntu.com/10711795/
[3] https://launchpadlibrarian.net/200211036/journal.txt