Get on the D-BUS

 
D-BUS' initial goal is to be a replacement for CORBA and DCOP, the remote object systems used in GNOME and KDE, respectively. 
 
D-BUS, as a full-featured IPC and object system, has several intended uses. First, D-BUS can perform basic application IPC, allowing one process to shuttle data to another—think UNIX domain sockets on steroids. Second, D-BUS can facilitate sending events, or signals, through the system, allowing different components in the system to communicate and ultimately to integrate better. For example, a Bluetooth daemon can send an incoming call signal that your music player can intercept, muting the volume until the call ends. Finally, D-BUS implements a remote object system, letting one application request services and invoke methods from a different object—think CORBA without the complications.
注:以上这段精辟的论述,从3个层面描述了D-Bus的功能 / 作用。这也正是 D-Bus 的目标。

Why D-BUS Is Unique

D-BUS is unique from other IPC mechanisms in several ways. First, the basic unit of IPC in D-BUS is a message, not a byte stream. In this manner, D-BUS breaks up IPC into discrete messages, complete with headers (metadata) and a payload (the data). The message format is binary, typed, fully aligned and simple. It is an inherent part of the wire protocol. This approach contrasts with other IPC mechanisms where the lingua franca is a random stream of bytes, not a discrete message. (上述为通讯协议上的区别)
 
Second, D-BUS is bus-based. The simplest form of communication is process to process. D-BUS, however, provides a daemon  known as the message bus daemon, that routes messages between processes on a specific bus. In this fashion, a bus topology is formed, allowing processes to speak to one or more applications at the same time. Applications can send to or listen for various events on the bus. (关于BUS类型的拓扑结构,应该是D-Bus与其他IPC最大的区别)
 
A final unique feature is the creation of not one but two of these buses, the system bus and the session bus. The system bus is global, system-wide and runs at the system level. All users of the system can communicate over this bus with the proper permissions, allowing the concept of system-wide events. The session bus, however, is created during user login and runs at the user, or session, level. This bus is used solely by a particular user, in a particular login session, as an IPC and remote object system for the user's applications.

D-BUS Concepts

Messages are sent to objects. Objects are addressed using path names, such as /org/cups/printers/queue. Processes on the message bus are associated with objects and implemented interfaces on that object.
 
 
D-BUS supports multiple message types, such as signals, method calls, method returns and error messages. Signals are notification that a specific event has occurred. They are simple, asynchronous, one-way heads-up messages. Method call messages allow an application to request the invocation of a method on a remote object. Method return messages provide the return value resulting from a method invocation. Error messages provide exceptions in response to a method invocation.
 
Big Conceptual Picture :  Address -> [Bus Name] -> Path -> Interface -> Method
bus name是可选的,除非是希望把消息送到特定的应用中才需要。interface也是可选的,有一些历史原因,DCOP不需要指定接口,因为DCOP在同一个对象中禁止同名的方法。
 
D-BUS is fully typed and type-safe. Both a message's header and payload are fully typed. Valid types include byte, Boolean, 32-bit integer, 32-bit unsigned integer, 64-bit integer, 64-bit unsigned integer, double-precision floating point and string. A special array type allows for the grouping of types. A DICT type allows for dictionary-style key/value pairs.
 
D-BUS is secure. It implements a simple protocol based on SASL profiles for authenticating one-to-one connections. On a bus-wide level, the reading of and the writing to messages from a specific interface are controlled by a security system. An administrator can control access to any interface on the bus. The D-BUS daemon was written from the ground up with security in mind.
 
注:以上是一些精简的概念说明,但非常到位。如果想得到更详细的说明,参考官网: https://www.freedesktop.org/wiki/IntroductionToDBus/

Why D-BUS?

These concepts make nice talk, but what is the benefit? First, the system-wide message bus is a new concept. A single bus shared by the entire system allows for propagation of events, from the kernel (see The Kernel Event Layer sidebar) to the uppermost applications on the system. Linux, with its well-defined interfaces and clear separation of layers, is not very integrated. D-BUS' system message bus improves integration without compromising fine engineering practices. Now, events such as disk full and printer queue empty or even battery power low can bubble up the system stack, available for whatever application cares, allowing the system to respond and react. The events are sent asynchronously, and without polling.

The Kernel Event Layer

The Kernel Event Layer is a kernel-to-user communication mechanism that uses a high-speed netlink socket(是否就是 UNIX Domain Socket?) to communicate asynchronously with user space. This mechanism can be tied into D-BUS, allowing the kernel to send D-BUS signals!
 
The Kernel Event Layer is tied to sysfs, the tree of kobjects that lives at /sys on modern Linux systems. Each directory in sysfs is tied to a kobject, which is a structure in the kernel used to represent objects; sysfs is an object hierarchy exported as a filesystem.
 
Each Kernel Event Layer event is modeled as though it originated from a sysfs path. Thus, the events appear as if they emit from kobjects. The sysfs paths are easily translatable to D-BUS paths, making the Kernel Event Layer and D-BUS a natural fit. This Kernel Event Layer was merged into the 2.6.10-rc1 kernel.
 
Second, the session bus provides a mechanism for IPC and remote method invocation, possibly providing a unified system between GNOME and KDE. D-BUS aims to be a better CORBA than CORBA and a better DCOP than DCOP, satisfying the needs of both projects while providing additional features.
 
And, D-BUS does all this while remaining simple and efficient.
 

桌面应用程序通信
典型的桌面都会有多个应用程序在运行,而且,它们经常需要彼此进行通信。DCOP 是一个用于 KDE 的 解决方案,但是它依赖于 Qt,所以不能用于其他桌面环境之中。类似的,Bonobo 是一个用于 GNOME 的 解决方案,但是非常笨重,因为它是基于 CORBA 的。它还依赖于 GObject,所以也不能用于 GNOME 之外。 D-BUS 的目标是将 DCOP 和 Bonobo 替换为简单的 IPC,并集成这两种桌面环境。由于尽可能地减少了 D-BUS 所需的依赖,所以其他可能会使用 D-BUS 的应用程序不用担心引入过多依赖。
 
桌面/操作系统通信
术语“操作系统”在这里不仅包括内核,还包括系统后台进程。例如,通过使用 D-BUS 的 udev (Linux 2.6 中取代 devfs 的, 提供动态 /dev 目录),当设备(比如一个 USB 照相机)插入时会发放出一个信号。 这样可以更紧密地将硬件集成到桌面中,从而改善用户体验。
 
客户端
在客户端使用DBUS比较简单,首先,从DBUS_BUS_SESSION类型的DBUS后台获得一个连接,再从这个连接创建得到一个对象的代理,以后对对象的所有操作都将通过这个代理来完成。
得到服务代理后,可以在应用程序的各个地方通过对象代理的方法使用函数想对象发出一个方法调用的消息。请求对象的服务,可以发送异步的方法(异步服务),也可以发送同步方法(同步服务),方法是同步还是异步有对象定义。
 
服务端
在服务器进程启动后,调用函数dbus_g_object_type_install_info将对象的安装信息结构告诉DBUS,随后,从DBUS_BUS_SESSION类型的DBUS获得一个连接,再从这个连接得到一个DBUS对象的代理。通过这个DBUS代理调用方法RequestName为这个连接得到一个命名,客户端应用可以使用这个名字将请求消息发送到连接。接着,服务器进程创建一个指定类型的对象(glib对象)。
其中安装信息由XML文件,通过dbus-binding-tool转换成对象的头文件。
 
消息
消息由消息头和消息体组成。消息头由消息的固有字段信息组成。消息体由一串字符串值组成。消息体的每个字符串值的意义由消息头中的描述指定,消息头的长度必须是8的倍数,相应的,消息体由8的倍数处开始。
 
Tools
  • 要查看Dbus总线上的服务和对象可以借助d-feet 和qdbusviewer
  • 要发送信号可以使用dbus-send
  • 要查看Dbus上的消息流可以使用dbus-monitor
 

思考:

  1. Dbus几乎集成在了Linux所有发行版中,作为系统级的IPC形式(甚至你没有安装X11,并且以init3模式启动,见附图),在于其作为一个管理工具,为系统间的程序提供了交互模式,且已经被各类App所接受。正如前面例子里讲的,当插入耳机,音频程序会默认根据dbus信号切换输出模式。
  2. 文中提到了通过bus daemon搭建起总线拓扑结构(a bus topology),那么,总线拓扑结构是什么样的呢?与MQ的broker结构(星形拓扑)有何区别?
  3. 我们知道,socket都是用于点对点通讯的,那么前面这个问题最明显的答案就是——星型拓扑。
  4. 在Why DBus中,最后提到了without polling?真的吗?那为什么客户端 / 服务端编程都必须依赖一个 MainLoop 循环呢?难道不是为了同步操作吗?
  5. 深入研究“内核事件”,Linux将内核封装成了怎么样的一种对象? 
  6. SessionBus的Proxy模式分析,以及远程对象调用——是否等同于RPC?

猜你喜欢

转载自www.cnblogs.com/brt3/p/9613346.html