检测D总线上禁止的关机

时间:2018-12-03 23:55:37

标签: linux systemd dbus

我使用x86_64 Debian 9 Stretch。我运行systemd-inhibit cat,然后在另一个控制台systemctl poweroff中运行。正确禁止关机。根据{{​​3}},应该发射信号PrepareForShutdown(false),但我看不到它。我使用dbus-monitor --system并使用python程序观看dbus:

#!/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()

程序不打印任何内容。 dbus-monitor会输出一些晦涩的消息(看起来像是在调用ListInhibitors)。

信号没有发出还是我听不见?我的目标是通过监听D-Bus来检测禁止的关机,我该怎么办?

编辑:使用非延迟禁止时,关闭请求只是被丢弃,信号不触发。但是,如果我通过systemd-inhibit --mode=delay --what=shutdown cat使用延迟锁定,则会触发PrepareForShutdown信号。

1 个答案:

答案 0 :(得分:1)

  

信号没有发出还是我听不见?

不确定。我的猜测是systemd仅向已采取延迟锁定的进程发出信号(单播信号发出),因为如果您documentation page收听PrepareForShutdown >不先进行延迟锁定。

检查此方法的方法是读取systemd source code

  

我的目标是通过监听D-Bus来检测禁止的关机,我该怎么办?

如果我在一个终端中运行sudo dbus-monitor --system,然后在另一终端中运行systemd-inhibit cat,则会看到以下信号发射:

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 [
   ]

因此,您可以监视服务/org/freedesktop/login1公开的org.freedesktop.login1对象的属性更改,并查看其BlockInhibitedDelayInhibited属性的更改时间。这些属性中的任何一个包含shutdown时,都将禁止关机。它们记录在the same documentation page上:

  

BlockInhibitedDelayInhibited属性编码什么类型的   当前已锁定。这些字段是用冒号分隔的列表   shutdownsleepidlehandle-power-keyhandle-suspend-key,   handle-hibernate-keyhandle-lid-switch。该列表基本上是   特定的所有当前活动锁的What字段的并集   模式。