I use x86_64 Debian 9 Stretch. I run systemd-inhibit cat
and then in another console systemctl poweroff
. Shutdown correctly gets inhibited. According to this doc signal PrepareForShutdown(false)
is supposed to be emitted, but I can't see it. I watch dbus with dbus-monitor --system
and using a python program:
#!/usr/bin/env python
import dbus
import gobject
from dbus.mainloop.glib import DBusGMainLoop
def handle(*args):
print "PrepareForShutdown %s" % (args)
DBusGMainLoop(set_as_default=True) # integrate into gobject main loop
bus = dbus.SystemBus() # connect to system wide dbus
bus.add_signal_receiver( # define the signal to listen to
handle, # callback function
'PrepareForShutdown', # signal name
'org.freedesktop.login1.Manager', # interface
'org.freedesktop.login1' # bus name
)
loop = gobject.MainLoop()
loop.run()
The program prints nothing. The dbus-monitor
outputs few obscure messages (looks like smth calls ListInhibitors).
Is signal not being emited or I just can't catch it? My goal is to detect inhibited shutdown by listening D-Bus, how do I do it?
EDIT: Turned out when non-delayed inhibition is used, shutdown request just gets discarded, signal doesn't fire. But if I use delay lock via systemd-inhibit --mode=delay --what=shutdown cat
then PrepareForShutdown signal fires.
Is signal not being emited or I just can't catch it?
Not sure. My guess would be that systemd only emits the signal to processes which have taken a delay lock (unicast signal emission), as the documentation page has some pretty dire warnings about race conditions if you listen for PrepareForShutdown
without taking a delay lock first.
The way to check this would be to read the systemd source code.
My goal is to detect inhibited shutdown by listening D-Bus, how do I do it?
If I run sudo dbus-monitor --system
in one terminal, and then run systemd-inhibit cat
in another, I see the following signal emission:
signal time=1543917703.712998 sender=:1.9 -> destination=(null destination) serial=1150 path=/org/freedesktop/login1; interface=org.freedesktop.DBus.Properties; member=PropertiesChanged
string "org.freedesktop.login1.Manager"
array [
dict entry(
string "BlockInhibited"
variant string "shutdown:sleep:idle:handle-power-key:handle-suspend-key:handle-hibernate-key:handle-lid-switch"
)
]
array [
]
Hence you could watch for property changes on the /org/freedesktop/login1
object exposed by service org.freedesktop.login1
, and see when its BlockInhibited
or DelayInhibited
properties change. Shutdown is inhibited when either of those properties contains shutdown
. They are documented on the same documentation page:
The
BlockInhibited
andDelayInhibited
properties encode what types of locks are currently taken. These fields are a colon separated list ofshutdown
,sleep
,idle
,handle-power-key
,handle-suspend-key
,handle-hibernate-key
,handle-lid-switch
. The list is basically the union of theWhat
fields of all currently active locks of the specific mode.