After running updates, I use the wcheckrestart tool to see which libraries are updated, so I can restart the daemons that use them. That only works if Systemd allows me to.

After a package update, it could look like this:

# wcheckrestart 
  PID TTY      STAT   TIME COMMAND
  950 ?        Ss     0:00 /usr/sbin/sshd -D
  952 ?        Ss     0:02 /usr/bin/dbus-daemon --system --address=systemd: \
                             --nofork --nopidfile --systemd-activation

That means that sshd and dbus-daemon are using libraries that are deleted. If we did a security update we might still be running the old vulnerable code.

To fix, we restart the daemons:

# systemctl restart ssh

# systemctl restart dbus
Failed to restart dbus.service: Operation refused, unit dbus.service may be
requested by dependency only.
See system logs and 'systemctl status dbus.service' for details.

Bleh! Since Systemd we're not allowed to restart dbus. That's no good if I want to use the newest dbus dependencies.

$ wcheckrestart -vv
PID 952 /usr/bin/dbus-daemon --system --address=systemd: \
                    --nofork --nopidfile --systemd-activation 
    952 7f6346dec000-7f6346e36000 r-xp 00000000 fd:01 2878143 \
                    /lib/x86_64-linux-gnu/libdbus-1.so.3.14.6 (deleted)
    952 7f6346e36000-7f6347036000 ---p 0004a000 fd:01 2878143 \
                    /lib/x86_64-linux-gnu/libdbus-1.so.3.14.6 (deleted)
    952 7f6347036000-7f6347037000 r--p 0004a000 fd:01 2878143 \
                    /lib/x86_64-linux-gnu/libdbus-1.so.3.14.6 (deleted)
    952 7f6347037000-7f6347038000 rw-p 0004b000 fd:01 2878143 \
                    /lib/x86_64-linux-gnu/libdbus-1.so.3.14.6 (deleted)

There are updates to /lib/x86_64-linux-gnu/libdbus-1.so, so I do want it restarted.

We'll have to hack a bit in the /lib/systemd/system/dbus.service file. It explicitly ignored the stop command and refuses a manual restart. Maybe there is a good reason, but I don't see it documented here. Let's fix it with this update:

[Unit]
Description=D-Bus System Message Bus
Documentation=man:dbus-daemon(1)
Requires=dbus.socket
# we don't properly stop D-Bus (see ExecStop=), thus disallow restart
#XXX:2016:allow-restart#RefuseManualStart=yes

[Service]
ExecStart=/usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation
ExecReload=/usr/bin/dbus-send --print-reply --system --type=method_call --dest=org.freedesktop.DBus / org.freedesktop.DBus.ReloadConfig
#XXX:2016:allow-restart#ExecStop=/bin/true
ExecStop=/bin/sh -c '/bin/kill -TERM $MAINPID && while /bin/kill -0 $MAINPID 2>/dev/null; do /bin/sleep 0.1; done'
KillMode=none
OOMScoreAdjust=-900

Commenting out the RefuseManualStart=yes and replacing ExecStop= makes it restart like expected. Don't forget to systemctl daemon-reload after updating the file.

Do note that one or more dependent services may stop (e.g. Accountsservice) upon dbus restart. You'll have to manage that yourself (possibly with the help of psdiff).

dbus restart systemd apt