D-Bus是Linux桌面的耻辱

发布: (2025年12月16日 GMT+8 03:07)
9 min read

请提供您希望翻译的完整文本内容(除了已经给出的 Source 链接之外),这样我才能为您进行准确的简体中文翻译。谢谢!

什么是 D-Bus?

大家都听说过 D-Bus,但它到底是什么?

D-Bus 的理念相当简单:让应用程序、服务以及其他 事物 以一种方式公开方法或属性,供其他应用在同一个总线上查找。

想象一个监测天气的服务。与其让每个应用都知道如何与每个天气服务通信——或者更糟的是自己实现一个——它们可以连接到总线,发现任何公开天气 API 的服务,并使用它。

很棒,对吧?而且,这个想法确实很妙。

出了什么问题?

D-Bus 是一个 宽容无组织宽恕 的总线。这三个特性导致了任何协议、语言或系统中最大、最根本、最概念性的错误之一。

最重要的错误是:

  • 总线上的对象可以注册它们想要的任何内容。
  • 总线上的对象可以以它们想要的任何方式、在它们想要的任何时间调用任何东西。
  • 协议允许——甚至鼓励——供应商特定的未检查垃圾。

在实践中,这导致 “输入垃圾,输出垃圾”。

D-Bus 标准,第一部分

应用需要通信,对吧?我们在哪里能找到方法?

呃……大概在网上吧。没人真的知道,因为文档散落、未完成、难以阅读或错综复杂。没有客户端能始终如一地遵循它们。

让我们看看一些“宝藏”(实际文档):

Image 1
真正安全。

Image 2
我猜服务实现者应该学习 telepathy。

Image 3
那它是草案还是被广泛使用?

D‑Bus 标准是一团糟——前提是双方的实现者真的遵循它们(实际上他们经常不遵循,正如我们将看到的)。

D-Bus 标准,第二部分

好吧,假设我们已经有了一个标准并且已经理解它。太棒了!现在…

没人他妈在乎,真的。即使你阅读了规范,也没有任何东西指引或强制你遵守它。你可以随意发送匿名调用。

个人经历

当我在编写 xdg-desktop-portal-hyprland 时,需要使用几个 D‑Bus 协议(xdg portal 在 D‑Bus 上运行)。门户文档列出了这些协议,于是我实现了它们。效果大致可用。

随后我加入了 restore tokens,它们允许应用恢复之前保存的共享配置。在这里,D‑Bus 完全失效。

没有任何应用——他妈的真的没有——遵循规范。我写了一个符合规范的机制,却没有任何人使用。为什么?因为它们全部使用了一个凭空出现的不同规范;我根本找不到任何文档。最后我只能查看 KDE 的实现并模仿它。

有趣的事实: 这仍然是现状! 规范在 SelectSourcesStart 上宣传了一个 restore_token 字符串属性,但没有任何应用使用它;它们改用 options 中的 restore_data

D-Bus 标准,第三部分

一句话:变体。一半的 D‑Bus 协议要么使用这种 BS,要么使用 a{sv}(字符串 + 变体 的数组)在某处传递。

在核心规范中允许这种松散类型的数据应该被禁止。它让应用程序可以在网络上随意发送垃圾数据,并期望对方能够理解。这种模式已经被多次尝试(例如 X atoms),并屡屡导致灾难。

D-Bus standards, part 4

听说过权限吗?D‑Bus 开发者也没听说过。D‑Bus 的安全性极低:所有人都能看到所有内容并调用任何东西。如果一个应用缺乏特定的安全机制,就会一团乱。更重要的是,没有通用的“拒绝”概念;协议要么自行发明,要么默默失败。

这就是 Flatpak 应用无法看到你的会话总线的主要原因。

D-Bus 标准,第5部分

KWallet 或 GNOME Keyring 怎么样?它们本应是用于签名密钥、密码等的“机密存储”,并受密码保护。

实际上,一旦存储被解锁,任何总线上的应用都可以读取所有机密。不是开玩笑——在你输入密码后,任何应用都可以悄悄读取所有内容。

受够了

我已经受够了在我的应用中使用 D‑Bus。为我的生态系统提供一个会话(以及以后系统)总线会很有帮助,但我绝不能容忍 D‑Bus 那种彻底的混乱。

所以我正从头开始编写一个全新的总线,完全不复制、不兼容,也不承认 D‑Bus。D‑Bus 中塞满了太多愚蠢的想法,我拒绝让它们污染我的系统。

XKCD 927

许多人在每次新的实现时都引用这幅 XKCD 漫画,但情况并不相同。

例如,在 Wayland 中,一旦切换就放弃了 X;你不能同时运行 X11 会话和 Wayland 会话。不过,你 can 运行两个、三个,甚至 17 个会话总线。没有任何东西阻止你这么做。这也是 gradual 迁移成为可能的原因。总线之间不能直接通信,但你可以创建一个代理客户端,将 D‑Bus API 翻译成新的 API。

线协议

我首先关注的是 hyprwire。我需要一个用于 Hypr* 工具(如 hyprlauncherhyprpaper 等)的线协议。

Hyprwire 受 Wayland 方法的启发。它最重要的优势包括:

  • 一致性 – 线协议强制类型和消息参数。没有 a{sv},也没有“随便发点什么吧”的情况。
  • 简洁性 – 协议快速且简单。没有增加烦恼的复杂结构体类型。
  • 速度 – 快速的握手和协议交换;连接能够迅速建立。

Hyprwire 已经在 hyprpaperhyprlauncher 以及 hyprctl 的部分功能中用于 IPC,并且表现良好。

总线

总线叫做 hyprtavern。它并不完全等同于 D‑Bus,而更像是一间酒馆。

应用程序在总线上注册对象,这些对象公开由这些协议定义的协议和关键属性。其他应用程序可以通过连接总线来发现这些对象。

在某种意义上,hyprtavern 像一个酒馆:每个应用都是一个客户端,可以宣传它所使用的语言,如果两个应用共享同一种语言,就可以开始对话。

相较于 D‑Bus 的整体改进(顺序不分先后)

  • 权限处理(不完整列表)
    (出于简洁省略了进一步细节。)
Back to Blog

相关文章

阅读更多 »

Linux 桌面上的 D-Bus 问题

D‑Bus 是什么?每个人都听说过 D‑Bus,但它到底是什么?D‑Bus 的理念很简单:让应用程序、服务以及其他事物公开方法或 p…

决定论并非智能的对立面

引言 在现代系统中,我们常常将 nondeterminism 视为一种特性。当某事表现出不可预测的行为时,我们会把它标记为 “emergent” 或 “complex”。 那种 fra...