D-Bus 有什么实际用途?

D-Bus 有什么实际用途?

dbus应该提供“一种让应用程序相互交谈的简单方法”。

但我仍然不确定它实际上有什么用。我从未见过有用的情况dbus,我只看到某些组件遇到错误的警告dbus,例如当我从命令行启动终结器时(以便我可以看到错误):

Error retrieving accessibility bus address: org.freedesktop.DBus.Error.ServiceUnknown: The name org.a11y.Bus was not provided by any .service files

NO_AT_BRIDGE=1我通过添加到 摆脱了上述错误/etc/environment。我不知道那是做什么的。

几乎所有 GUI 应用程序似乎都与dbus.有些允许在没有 的情况下启动dbus,即:

terminator --no-dbus

我认为行为没有什么不同。什么应该停止工作,什么时候terminator开始没有dbus

另外,我尝试禁用各种 dbus 组件以查看哪些停止工作:

我删除/etc/X11/Xsession.d/95dbus_update-activation-env只是为了看看会发生什么。它包含以下代码:

if [ -n "$DBUS_SESSION_BUS_ADDRESS" ] && [ -x "/usr/bin/dbus-update-activation-environment" ]; then
  # subshell so we can unset environment variables
  (
    # unset login-session-specifics
    unset XDG_SEAT
    unset XDG_SESSION_ID
    unset XDG_VTNR

    # tell dbus-daemon --session to put the Xsession's environment in activated services' environments
    dbus-update-activation-environment --verbose --all
  )
fi

据我所知,一切都一样。上述脚本的目的是什么?

在什么情况下,我的应用程序通过 相互通信会有用dbus

是否有一些应用程序没有 就无法运行dbus

我的系统是 Debian Buster,我使用的是普通的 openbox 环境(没有任何桌面环境,如 Gnome 或 KDE)

答案1

dbus正如您所说:它允许应用程序之间进行双向通信。


对于你提到的具体例子terminator。从终结者的手册页, 我们看:

--new-tab
    If this is specified and Terminator is already running, DBus 
    will be used to spawn a new tab in the first Terminator window.

因此,如果您从另一个终端(konsole、xterm、gnome-terminal)执行此操作:

$ terminator &
$ terminator --new-tab &

您将看到第一个命令打开一个新窗口。第二个命令在第一个窗口中打开一个新选项卡。这是由第二个进程使用 dbus 查找第一个进程,要求它打开一个新选项卡,然后退出来完成的。

如果您从另一个终端执行此操作:

$ terminator --no-dbus &
$ terminator --new-tab &

您将看到第一个命令打开一个新窗口。第二个命令无法找到第一个窗口的 dbus,因此它启动一个新窗口。我安装了终结者来测试这一点,这是真的。

此外,我怀疑 polkit 也会受到影响。 Polkit 使用 dbus 来提升 GUI 应用程序的权限。这就像sudoGUI 世界的一样。如果您在 gnome 中,并且在要求您输入管理员密码时看到整个屏幕被覆盖,这就是 polkit 的作用。我怀疑terminator如果您有--no-dbus.它要么无法进行身份验证,要么回退到某些终端身份验证。从terminator尝试pkexec ls。这将以ls提升的权限运行。看看使用和不使用该选项是否有所不同--no-dbus。我的窗口管理器(i3)中没有 polkit 代理,所以我无法测试这个代理。


我主要了解 systemd 方面的 dbus,所以这就是我其余答案的来源。

是否有一些应用程序没有 就无法运行dbus

是的。拿systemctlsystemctl status将向 发出查询"org.freedesktop.systemd1",并将其呈现给您。 systemctl start将调用 dbus 方法并将单位作为参数传递给该方法。 systemd接听电话并执行操作。

如果您想采取行动来响应 systemd 单元(即 foo.service)更改状态,您可以获取org.freedesktop.DBus.Properties带有 path/org/freedesktop/systemd1/unit/foo_2eservice和 member 的接口的文件描述符PropertiesChanged。在那个 FD 上设置一个inotify,你突然就有了一种方法来对服务的启动、停止、失败等做出反应。

如果您想查看 systemd dbus 上特定单元(即ssh.service)可用的内容,请尝试以下命令:

busctl introspect \
    org.freedesktop.systemd1 \
    /org/freedesktop/systemd1/unit/ssh_2eservice
NAME                                TYPE      SIGNATURE       RESULT/VALUE                             FLAGS
org.freedesktop.DBus.Introspectable interface -               -                                        -
.Introspect                         method    -               s                                        -
org.freedesktop.DBus.Peer           interface -               -                                        -
.GetMachineId                       method    -               s                                        -
.Ping                               method    -               -                                        -
org.freedesktop.DBus.Properties     interface -               -                                        -
.Get                                method    ss              v                                        -
.GetAll                             method    s               a{sv}                                    -
.Set                                method    ssv             -                                        -
.PropertiesChanged                  signal    sa{sv}as        -                                        -
org.freedesktop.systemd1.Service    interface -               -                                        -
.AttachProcesses                    method    sau             -                                        -
.GetProcesses                       method    -               a(sus)                                   -
.AllowedCPUs                        property  ay              0                                        -
.AllowedMemoryNodes                 property  ay              0                                        -
.AmbientCapabilities                property  t               0                                        const
.AppArmorProfile                    property  (bs)            false ""                                 const
.BindPaths                          property  a(ssbt)         0                                        const
.BindReadOnlyPaths                  property  a(ssbt)         0                                        const
.BlockIOAccounting                  property  b               false                                    -
.BlockIODeviceWeight                property  a(st)           0                                        -
.BlockIOReadBandwidth               property  a(st)           0                                        -
.BlockIOWeight                      property  t               18446744073709551615                     -
.BlockIOWriteBandwidth              property  a(st)           0                                        -
.BusName                            property  s               ""                                       const
.CPUAccounting                      property  b               false                                    -
.CPUAffinity                        property  ay              0                                        const
.CPUAffinityFromNUMA                property  b               false                                    const
.CPUQuotaPerSecUSec                 property  t               18446744073709551615                     -
.CPUQuotaPeriodUSec                 property  t               18446744073709551615                     -
.CPUSchedulingPolicy                property  i               0                                        const
.CPUSchedulingPriority              property  i               0                                        const
.CPUSchedulingResetOnFork           property  b               false                                    const
.CPUShares                          property  t               18446744073709551615                     -
.CPUUsageNSec                       property  t               18446744073709551615                     -
.CPUWeight                          property  t               18446744073709551615                     -
.CacheDirectory                     property  as              0                                        const
.CacheDirectoryMode                 property  u               493                                      const
.CapabilityBoundingSet              property  t               18446744073709551615                     const
.CleanResult                        property  s               "success"                                emits-change
.ConfigurationDirectory             property  as              0                                        const
.ConfigurationDirectoryMode         property  u               493                                      const
.ControlGroup                       property  s               "/system.slice/ssh.service"              -
.ControlPID                         property  u               0                                        emits-change
.CoredumpFilter                     property  t               51                                       const
.DefaultMemoryLow                   property  t               0                                        -
.DefaultMemoryMin                   property  t               0                                        -
.Delegate                           property  b               false                                    -
.DelegateControllers                property  as              0                                        -
.DeviceAllow                        property  a(ss)           0                                        -
.DevicePolicy                       property  s               "auto"                                   -
.DisableControllers                 property  as              0                                        -
.DynamicUser                        property  b               false                                    const
.EffectiveCPUs                      property  ay              0                                        -
.EffectiveMemoryNodes               property  ay              0                                        -
.Environment                        property  as              0                                        const
.EnvironmentFiles                   property  a(sb)           1 "/etc/default/ssh" true                const
.ExecCondition                      property  a(sasbttttuii)  0                                        emits-invalidation
.ExecConditionEx                    property  a(sasasttttuii) 0                                        emits-invalidation
.ExecMainCode                       property  i               0                                        emits-change
.ExecMainExitTimestamp              property  t               0                                        emits-change
.ExecMainExitTimestampMonotonic     property  t               0                                        emits-change
.ExecMainPID                        property  u               835                                      emits-change
.ExecMainStartTimestamp             property  t               1597235861087584                         emits-change
.ExecMainStartTimestampMonotonic    property  t               5386565                                  emits-change
.ExecMainStatus                     property  i               0                                        emits-change
.ExecReload                         property  a(sasbttttuii)  2 "/usr/sbin/sshd" 2 "/usr/sbin/sshd" "… emits-invalidation
.ExecReloadEx                       property  a(sasasttttuii) 2 "/usr/sbin/sshd" 2 "/usr/sbin/sshd" "… emits-invalidation
.ExecStart                          property  a(sasbttttuii)  1 "/usr/sbin/sshd" 3 "/usr/sbin/sshd" "… emits-invalidation
.ExecStartEx                        property  a(sasasttttuii) 1 "/usr/sbin/sshd" 3 "/usr/sbin/sshd" "… emits-invalidation
.ExecStartPost                      property  a(sasbttttuii)  0                                        emits-invalidation
.ExecStartPostEx                    property  a(sasasttttuii) 0                                        emits-invalidation
.ExecStartPre                       property  a(sasbttttuii)  1 "/usr/sbin/sshd" 2 "/usr/sbin/sshd" "… emits-invalidation
.ExecStartPreEx                     property  a(sasasttttuii) 1 "/usr/sbin/sshd" 2 "/usr/sbin/sshd" "… emits-invalidation
.ExecStop                           property  a(sasbttttuii)  0                                        emits-invalidation
.ExecStopEx                         property  a(sasasttttuii) 0                                        emits-invalidation
.ExecStopPost                       property  a(sasbttttuii)  0                                        emits-invalidation
.ExecStopPostEx                     property  a(sasasttttuii) 0                                        emits-invalidation
.FileDescriptorStoreMax             property  u               0                                        const
.FinalKillSignal                    property  i               9                                        const
.GID                                property  u               4294967295                               emits-change
.Group                              property  s               ""                                       const
.GuessMainPID                       property  b               true                                     const
.IOAccounting                       property  b               false                                    -
.IODeviceLatencyTargetUSec          property  a(st)           0                                        -
.IODeviceWeight                     property  a(st)           0                                        -
.IOReadBandwidthMax                 property  a(st)           0                                        -
.IOReadBytes                        property  t               18446744073709551615                     -
.IOReadIOPSMax                      property  a(st)           0                                        -
.IOReadOperations                   property  t               18446744073709551615                     -
.IOSchedulingClass                  property  i               0                                        const
.IOSchedulingPriority               property  i               0                                        const
.IOWeight                           property  t               18446744073709551615                     -
.IOWriteBandwidthMax                property  a(st)           0                                        -
.IOWriteBytes                       property  t               18446744073709551615                     -
.IOWriteIOPSMax                     property  a(st)           0                                        -
.IOWriteOperations                  property  t               18446744073709551615                     -
.IPAccounting                       property  b               false                                    -
.IPAddressAllow                     property  a(iayu)         0                                        -
.IPAddressDeny                      property  a(iayu)         0                                        -
.IPEgressBytes                      property  t               18446744073709551615                     -
.IPEgressFilterPath                 property  as              0                                        -
.IPEgressPackets                    property  t               18446744073709551615                     -
.IPIngressBytes                     property  t               18446744073709551615                     -
.IPIngressFilterPath                property  as              0                                        -
.IPIngressPackets                   property  t               18446744073709551615                     -
.IgnoreSIGPIPE                      property  b               true                                     const
.InaccessiblePaths                  property  as              0                                        const
...skipping...
.CollectMode                        property  s               "inactive"                               const
.ConditionResult                    property  b               true                                     emits-change
.ConditionTimestamp                 property  t               1597235861034899                         emits-change
.ConditionTimestampMonotonic        property  t               5333881                                  emits-change
.Conditions                         property  a(sbbsi)        1 "ConditionPathExists" false true "/et… emits-invalidation
.ConflictedBy                       property  as              0                                        const
.Conflicts                          property  as              1 "shutdown.target"                      const
.ConsistsOf                         property  as              0                                        const
.DefaultDependencies                property  b               true                                     const
.Description                        property  s               "OpenBSD Secure Shell server"            const
.Documentation                      property  as              2 "man:sshd(8)" "man:sshd_config(5)"     const
.DropInPaths                        property  as              0                                        const
.FailureAction                      property  s               "none"                                   const
.FailureActionExitStatus            property  i               -1                                       const
.Following                          property  s               ""                                       -
.FragmentPath                       property  s               "/lib/systemd/system/ssh.service"        const
.FreezerState                       property  s               "running"                                emits-change
.Id                                 property  s               "ssh.service"                            const
.IgnoreOnIsolate                    property  b               false                                    const
.InactiveEnterTimestamp             property  t               0                                        emits-change
.InactiveEnterTimestampMonotonic    property  t               0                                        emits-change
.InactiveExitTimestamp              property  t               1597235861039525                         emits-change
.InactiveExitTimestampMonotonic     property  t               5338505                                  emits-change
.InvocationID                       property  ay              16 90 215 118 165 228 162 72 57 179 144… emits-change
.Job                                property  (uo)            0 "/"                                    emits-change
.JobRunningTimeoutUSec              property  t               18446744073709551615                     const
.JobTimeoutAction                   property  s               "none"                                   const
.JobTimeoutRebootArgument           property  s               ""                                       const
.JobTimeoutUSec                     property  t               18446744073709551615                     const
.JoinsNamespaceOf                   property  as              0                                        const
.LoadError                          property  (ss)            "" ""                                    const
.LoadState                          property  s               "loaded"                                 const
.Names                              property  as              2 "ssh.service" "sshd.service"           const
.NeedDaemonReload                   property  b               false                                    const
.OnFailure                          property  as              0                                        const
.OnFailureJobMode                   property  s               "replace"                                const
.PartOf                             property  as              0                                        const
.Perpetual                          property  b               false                                    const
.PropagatesReloadTo                 property  as              0                                        const
.RebootArgument                     property  s               ""                                       const
.Refs                               property  as              0                                        -
.RefuseManualStart                  property  b               false                                    const
.RefuseManualStop                   property  b               false                                    const
.ReloadPropagatedFrom               property  as              0                                        const
.RequiredBy                         property  as              0                                        const
.Requires                           property  as              3 "system.slice" "-.mount" "sysinit.tar… const
.RequiresMountsFor                  property  as              1 "/run/sshd"                            const
.Requisite                          property  as              0                                        const
.RequisiteOf                        property  as              0                                        const
.SourcePath                         property  s               ""                                       const
.StartLimitAction                   property  s               "none"                                   const
.StartLimitBurst                    property  u               5                                        const
.StartLimitIntervalUSec             property  t               10000000                                 const
.StateChangeTimestamp               property  t               1597235861208937                         emits-change
.StateChangeTimestampMonotonic      property  t               5507917                                  emits-change
.StopWhenUnneeded                   property  b               false                                    const
.SubState                           property  s               "running"                                emits-change
.SuccessAction                      property  s               "none"                                   const
.SuccessActionExitStatus            property  i               -1                                       const
.Transient                          property  b               false                                    const
.TriggeredBy                        property  as              0                                        const
.Triggers                           property  as              0                                        const
.UnitFilePreset                     property  s               "enabled"                                -
.UnitFileState                      property  s               "enabled"                                -
.WantedBy                           property  as              1 "multi-user.target"                    const
.Wants                              property  as              0                                        const

由此可见dbus接口的功能相当强大。

您可能会问:为什么这些应用程序不通过套接字或文件进行通信?

DBus 提供了一个通用接口。您不需要根据正在交谈的应用程序使用不同的逻辑来调用方法或检查属性。您只需要知道路径的名称即可。

我用它systemd作为例子,因为这是我最理解的,但在大多数桌面上都有大量 dbus 的用途。从身份验证到显示设置的所有内容都可以在 dbus 上使用。

答案2

@Stewart 已经对 D-Bus 做了一个非常深入的回答,但我想用关于 D-Bus 设计的高级想法来修改它。

UNIX 和Linux 系统上进程间通信(IPC) 的“传统”方式直接使用套接字,例如进程A 打开/var/run/a.socket,进程B 对其进行读/写。对于旨在相互通信的紧密结合的程序来说,这非常有效。

但是,您可能希望在两个程序的进程之间进行通信,而在编写程序 A 时,程序 B 甚至不存在。 D-Bus 试图通过提供通信和服务发现协议来解决这个问题。这样,当编写A并且进程B实现接口b时,只需要存在接口b。

因此,您可以将 D-Bus 描述为 IPC“管理器”。

从历史上看,命令行界面 (CLI) 工具通常还使用 IPC 管理器(shell)通过管道与任意程序进行通信。这种方法的问题在于它不提供数据验证、标准化协议等。因此它只能由高级用户使用。一般而言,GUI 工具应该“隐形”地执行此操作。然而,越来越多的 CLI 工具开始使用 D-Bus,几乎作为sudo(1).因此,您可以作为非特权用户执行systemctl poweroff,它会提示您进行身份验证(这可以与 Windows 上的 UAC 进行比较)。根据您的 polkit 提供商,这甚至可能是 GUI 提示。至少在理论上,这种方法更加灵活,并且允许更细粒度的权限,并且无需 setuid 二进制文件(例如sudo)即可工作。这可以被视为一种安全功能。

当然,作为一种抽象,它引入了某种复杂性(至少在程序的依赖关系方面)。然而,越多的程序(理智地)使用它,负担就越小。你是否喜欢D-Bus以及目前的发展我无法告诉你。但由于当今计算的要求更加复杂,现代操作系统倾向于在内核之外提供许多关键服务(现在再次将历史内核内容移出微内核)。因此,如果您“只是”想要一个“简单”终端,那么所有这些可能会被认为是“臃肿”,但行业的需求是有充分理由的,并且越来越多的开发人员注意到使用 D-Bus 的优点。它是当今 shell 中旧管道的替代品(不是系统接口,实际上 D-Bus 使用pipe()等)。

答案3

在传统的 Unix 中,正在运行的程序之间通常很少有通信。每个程序都在完全独立的地址空间中运行,并且仅与内核交互。这种模型简单而健壮,但访问权限对于桌面环境来说大多过于粗略,并且在许多情况下实现细粒度的访问控制过于复杂。

内核改进访问控制的一个例子是文件系统——非特权程序可以向内核发送写请求,该请求会被转换为发送到硬盘的写请求,而不会违反程序之间的隔离。不过,这是一个相当复杂的层,对于用户可能想要连接 USB 记忆棒的现代桌面来说,控制仍然不够精细。

对于其他功能,例如声卡访问,内核仅实现了一个简单的访问模型:一旦程序访问了声卡,它就可以播放和录制声音,以及操作混音器控制,并且没有任何机制可以撤销该访问权限,除了终止程序。

在桌面环境中,我们想要一个更好的模型:浏览器应该只有在询问用户后才能够使用麦克风和网络摄像头,并且当用户注销时,任何正在运行的程序都应该失去麦克风访问权限,但如果用户想要整夜运行计算,这应该仍然是可能的。

X 窗口系统是在用户程序中执行访问控制的良好先例——通过向另一个程序发送请求来计算显示的最终屏幕内容来完成对窗口的渲染。请求是否转换为屏幕内容的可见更改取决于当前的访问控制设置:将窗口拉到前面可为该程序提供对屏幕空间区域的写访问权限,将其发送到后面则撤销该访问权限。

桌面环境现在提供了大量此类中介程序,因此对于每个功能都需要有一个通信协议和一种打开该程序句柄的方法。

dbus 提供通用协议和代理服务,其中程序可以请求连接到提供对特定功能的访问控制的程序。如果目标程序已经在运行,代理将仅转发请求,如果尚未运行,代理将根据需要启动该程序(如果它知道如何启动)。

Windows 上的等效功能是 COM/DCOM 与注册表的组合。

答案4

一切似乎仍然可以在 XFCE 下工作(某些桌面,例如 gnome 可能是更依赖于dbus)。我通过运行应用程序消防监狱因此,失去任何所谓的安全利益dbus并不是真正的问题。

dbus以下 Linux 发行版在没有& 的情况下似乎运行良好systemd

会有一些小问题,但如果你有足够的能力,这些问题很容易解决。

相关内容