Qt/C++ systemd 单位为 started/stopped 时的信号

Qt/C++ signal when systemd unit is started/stopped

我正在使用 systemd 的 dbus 接口来启动或停止服务。当我启动或停止一个单元时,我会向用户显示一个标签,上面写着 "unit xx started"。我使用 qdbusxml2cpp 生成的 xml 自省看起来像这样:

<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
 <interface name="org.freedesktop.systemd1.Unit">
  <property name="Id" type="s" access="read">
   <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
  </property>
  <property name="Names" type="as" access="read">
   <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
  </property>
  <property name="Following" type="s" access="read">
   <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/>
  </property>
  <property name="Requires" type="as" access="read">
   <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
  </property>
  <property name="Requisite" type="as" access="read">
   <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
  </property>
  <property name="Wants" type="as" access="read">
   <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
  </property>
  <property name="BindsTo" type="as" access="read">
   <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
  </property>
  <property name="PartOf" type="as" access="read">
   <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
  </property>
  <property name="RequiredBy" type="as" access="read">
   <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
  </property>
  <property name="RequisiteOf" type="as" access="read">
   <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
  </property>
  <property name="WantedBy" type="as" access="read">
   <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
  </property>
  <property name="BoundBy" type="as" access="read">
   <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
  </property>
  <property name="ConsistsOf" type="as" access="read">
   <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
  </property>
  <property name="Conflicts" type="as" access="read">
   <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
  </property>
  <property name="ConflictedBy" type="as" access="read">
   <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
  </property>
  <property name="Before" type="as" access="read">
   <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
  </property>
  <property name="After" type="as" access="read">
   <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
  </property>
  <property name="OnFailure" type="as" access="read">
   <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
  </property>
  <property name="Triggers" type="as" access="read">
   <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
  </property>
  <property name="TriggeredBy" type="as" access="read">
   <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
  </property>
  <property name="PropagatesReloadTo" type="as" access="read">
   <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
  </property>
  <property name="ReloadPropagatedFrom" type="as" access="read">
   <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
  </property>
  <property name="JoinsNamespaceOf" type="as" access="read">
   <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
  </property>
  <property name="RequiresMountsFor" type="as" access="read">
   <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
  </property>
  <property name="Documentation" type="as" access="read">
   <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
  </property>
  <property name="Description" type="s" access="read">
   <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
  </property>
  <property name="LoadState" type="s" access="read">
   <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
  </property>
  <property name="ActiveState" type="s" access="read">
  </property>
  <property name="SubState" type="s" access="read">
  </property>
  <property name="FragmentPath" type="s" access="read">
   <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
  </property>
  <property name="SourcePath" type="s" access="read">
   <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
  </property>
  <property name="DropInPaths" type="as" access="read">
   <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
  </property>
  <property name="UnitFileState" type="s" access="read">
   <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/>
  </property>
  <property name="UnitFilePreset" type="s" access="read">
   <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/>
  </property>
  <property name="StateChangeTimestamp" type="t" access="read">
  </property>
  <property name="StateChangeTimestampMonotonic" type="t" access="read">
  </property>
  <property name="InactiveExitTimestamp" type="t" access="read">
  </property>
  <property name="InactiveExitTimestampMonotonic" type="t" access="read">
  </property>
  <property name="ActiveEnterTimestamp" type="t" access="read">
  </property>
  <property name="ActiveEnterTimestampMonotonic" type="t" access="read">
  </property>
  <property name="ActiveExitTimestamp" type="t" access="read">
  </property>
  <property name="ActiveExitTimestampMonotonic" type="t" access="read">
  </property>
  <property name="InactiveEnterTimestamp" type="t" access="read">
  </property>
  <property name="InactiveEnterTimestampMonotonic" type="t" access="read">
  </property>
  <property name="CanStart" type="b" access="read">
   <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
  </property>
  <property name="CanStop" type="b" access="read">
   <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
  </property>
  <property name="CanReload" type="b" access="read">
   <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
  </property>
  <property name="CanIsolate" type="b" access="read">
   <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
  </property>
  <property name="Job" type="(uo)" access="read">
   <annotation name="org.qtproject.QtDBus.QtTypeName" value="DBusJob"/>
  </property>
  <property name="StopWhenUnneeded" type="b" access="read">
   <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
  </property>
  <property name="RefuseManualStart" type="b" access="read">
   <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
  </property>
  <property name="RefuseManualStop" type="b" access="read">
   <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
  </property>
  <property name="AllowIsolate" type="b" access="read">
   <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
  </property>
  <property name="DefaultDependencies" type="b" access="read">
   <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
  </property>
  <property name="OnFailureJobMode" type="s" access="read">
   <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
  </property>
  <property name="IgnoreOnIsolate" type="b" access="read">
   <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
  </property>
  <property name="NeedDaemonReload" type="b" access="read">
   <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
  </property>
  <property name="JobTimeoutUSec" type="t" access="read">
   <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
  </property>
  <property name="JobTimeoutAction" type="s" access="read">
   <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
  </property>
  <property name="JobTimeoutRebootArgument" type="s" access="read">
   <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
  </property>
  <property name="ConditionResult" type="b" access="read">
  </property>
  <property name="AssertResult" type="b" access="read">
  </property>
  <property name="ConditionTimestamp" type="t" access="read">
  </property>
  <property name="ConditionTimestampMonotonic" type="t" access="read">
  </property>
  <property name="AssertTimestamp" type="t" access="read">
  </property>
  <property name="AssertTimestampMonotonic" type="t" access="read">
  </property>
  <property name="Conditions" type="a(sbbsi)" access="read">
   <annotation name="org.qtproject.QtDBus.QtTypeName" value="UnitConditionList"/>
   <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/>
  </property>
  <property name="Asserts" type="a(sbbsi)" access="read">
   <annotation name="org.qtproject.QtDBus.QtTypeName" value="UnitConditionList"/>
   <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/>
  </property>
  <property name="LoadError" type="(ss)" access="read">
   <annotation name="org.qtproject.QtDBus.QtTypeName" value="UnitLoadError"/>
   <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
  </property>
  <property name="Transient" type="b" access="read">
   <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
  </property>
  <property name="StartLimitInterval" type="t" access="read">
   <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
  </property>
  <property name="StartLimitBurst" type="u" access="read">
   <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
  </property>
  <property name="StartLimitAction" type="s" access="read">
   <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
  </property>
  <property name="RebootArgument" type="s" access="read">
   <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/>
  </property>
  <method name="Start">
   <arg type="s" direction="in"/>
   <arg type="o" direction="out"/>
  </method>
  <method name="Stop">
   <arg type="s" direction="in"/>
   <arg type="o" direction="out"/>
  </method>
  <method name="Reload">
   <arg type="s" direction="in"/>
   <arg type="o" direction="out"/>
  </method>
  <method name="Restart">
   <arg type="s" direction="in"/>
   <arg type="o" direction="out"/>
  </method>
  <method name="TryRestart">
   <arg type="s" direction="in"/>
   <arg type="o" direction="out"/>
  </method>
  <method name="ReloadOrRestart">
   <arg type="s" direction="in"/>
   <arg type="o" direction="out"/>
  </method>
  <method name="ReloadOrTryRestart">
   <arg type="s" direction="in"/>
   <arg type="o" direction="out"/>
  </method>
  <method name="Kill">
   <arg type="s" direction="in"/>
   <arg type="i" direction="in"/>
  </method>
  <method name="ResetFailed">
  </method>
  <method name="SetProperties">
   <annotation name="org.qtproject.QtDBus.QtTypeName.In1" value="QVariantMap"/>
   <arg type="b" direction="in"/>
   <arg type="a(sv)" direction="in">
    <annotation name="org.qtproject.QtDBus.QtTypeName.In1" value="QVariantMap"/>
   </arg>
  </method>
 </interface>
</node>

问题是该单元也可以由第三方应用程序启动,这意味着我显示的消息将与实际系统状态不同步。我很困惑为什么当 运行 状态改变时,正在发射的装置上没有信号,或者我错过了什么?轮询实际状态是没有选择的。

systemd dbus 管理器公开了这个接口:

<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
 <interface name="org.freedesktop.DBus.Properties">
  <method name="Get">
   <arg name="interface" direction="in" type="s"/>
   <arg name="property" direction="in" type="s"/>
   <arg name="value" direction="out" type="v"/>
  </method>
  <method name="GetAll">
   <arg name="interface" direction="in" type="s"/>
   <arg name="properties" direction="out" type="a{sv}"/>
   <annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="QVariantMap"/>
  </method>
  <method name="Set">
   <arg name="interface" direction="in" type="s"/>
   <arg name="property" direction="in" type="s"/>
   <arg name="value" direction="in" type="v"/>
  </method>
  <signal name="PropertiesChanged">
   <arg type="s" name="interface"/>
   <arg type="a{sv}" name="changed_properties"/>
   <annotation name="org.qtproject.QtDBus.QtTypeName.Out1" value="QVariantMap"/>
   <arg type="as" name="invalidated_properties"/>
  </signal>
 </interface>
</node>