- 了解DBUS
1.概述
D-Bus是一种高级的进程间通信机制,它由freedesktop.org项目提供,使用GPL许可证发行。D-Bus的主要概念为总线,注册后的进程可通过总线接收或传递消息,进程也可注册后等待内核事件响应,例如等待网络状态的转变或者计算机发出关机指令。
D-Bus是Linux及其他类UNIX系统上的一种IPC(Interprocess communication)机制。相较于传统的管道(PIPE)、Socket等原生基于字节流的IPC方式,D-Bus提供了基于独立Message的传输方式,应用程序使用起来更加简单。D-Bus的设计初衷是为Linux桌面环境上的一系列应用程序提供通信方式,它的设计里保留了许多对上层框架设计考虑的元素。
D-Bus的常用架构与传统的Socket一对一通信模式不同,它基于中间消息路由转发的模式来实现, 如下图:
D-Bus默认提供两种BUS,系统BUS(system)和会话BUS(session)。系统BUS在每台机器上是惟一的,用于后台服务及操作系统之间的通信。会话BUS用于每个登录用户会话的应用程序之间的通信。每个BUS实例由一个bus-daemon进程来管理,由其负责消息路由转发。应用程序需要收发消息,需要连接到BUS实例上。BUS实例使用基于XML的配置文件来控制安全策略,如用户能否注册服务,能给哪些服务接口发送消息等等。
DBus的三层架构:
- 底层接口层:主要是通过libdbus这个函数库,使进程拥有使用DBus的能力。
- 总线层:主要是由Dbus 总线守护进程(daemon)提供的,在Linux/Qnx系统启动时运行,负责进程间的消息路由和传递,其中包括内核和桌面环境的消息传递。总线守护进程可同时与多个进程相连,并能把来自一个进程的消息路由到一个或者多个进程。
- 应用封装层:通过一系列基于特定应用程序框架将DBus的底层接口封装成友好的Wrapper库,供应用开发人员使用。
1.1.D-Bus概念
-
Service
也叫BUS Name,这个名称有些令人费解。它并不是指BUS实例的名称,而应该理解为进程连接到BUS实例之后的名称。BUS实例依据BUS Name转发消息。进程连接到BUS实例时,会由BUS实例自动分配一个惟一的连接名称,形式如:1.98, 但这个名称不是很容易记,可以注册更有实际意义的名称。自行注册的服务名称使用反向域名的方式,类似于JAVA中的类名。比如, 服务名称org.freedesktop.login1对应系统BUS上的systemd-logind服务。 -
object
一个D-Bus服务可以包含多个对象, 每个对象对外提供一组功能特性。它是一个独立处理消息的实体,也就是说消息的传送路径为对象到对象。不同的编程语言和库中,定义了自身领域内的对象,如JAVA中的java.lang.Object, GLIB中的GObject, QT中的QObject等。D-Bus使用通用的对象路径的方式来让更高层的接口来绑定到特定语言和库的对象中。这种对象路径类似于类UNIX系统中的文件路径,如/org/freedesktop/systemd。这种路径只是提供了对象的惟一标识符,不同的服务实现可以自行来决定是否需要使用其层次性的价值。 -
Interface
object支持一个或者多个接口,接口是一组方法和信号的集和。可以理解为方法(methods)和信号(signals)的命名空间。命名也是采用反向域名方式,如org.freedesktop.DBus。大多数编程语言的D-Bus绑定库会将这些接口映射为语言本身的结构,如JAVA中的Interface,C++的纯虚类。 -
Members
Interface中成员可以包含多个methods和signals。Methods表示能够被其他进程调用的操作,可以带有参数和响应结果。Signals是一种带有Payload的广播消息,进程可以定义自己感兴趣的Signals。这两种情形分别对应RPC(Remote Procedure Call)和Publish/Subscribe模式。
1.2.Configuration and Startup
Bus daemons are started using the dbus-launch command, which in turn runs dbus-daemon. Both take an option --config-file option to indicate a configuration file describing the bus being started. The standard buses have /etc/dbus-1/system.conf and /etc/dbus-1/session.conf as their respective configuration files.
Configuration files are in a simple XML-based format called busconfig.
1.3.Setup
Before trying to write anything is important to check if everything is running as it should and that you have the right privileges to debug and use system bus.
First of all, the dbus-daemon should be running. Why? Because it acts as a bridge between processes, receiving messages from the sender app and redirecting to the target app, which by the way is done via sockets. So, without dbus-daemon there is no D-Bus to work with.
ubuntu@ubuntu-xenial:~$ ps aux | grep dbus
message+ 1143 0.0 0.0 42908 3860 ? Ss 20:25 0:00 /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation
1.4.Debugging
There are two buses commonly used: the session bus and the system bus. Either may be used by any application, depending on what it is doing.
- To monitor the session bus: dbus-monitor
- To monitor the system bus:
create a file /etc/dbus-1/system-local.conf, with these contents:
<!DOCTYPE busconfig PUBLIC
"-//freedesktop//DTD D-Bus Bus Configuration 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig>
<policy user="root">
<allow eavesdrop="true"/>
<allow eavesdrop="true" send_destination="*"/>
</policy>
</busconfig>
When done debugging, it is wise to remove the policy snippet:
sudo rm /etc/dbus-1/system-local.conf
1.4.1.dbus-monitor
You can use dbus-monitor with the following options:
--system monitors the system message bus.
--session monitors the session message bus (default).
--profile uses the profiling output format.
--monitor uses the monitoring output format (default).
例如:
sudo dbus-monitor --system interface=org.freedesktop.login1.Manager
1.4.2.Filtering all the noise
If there is just too much information on the bus, pass a match rule like so:
dbus-monitor “type=signal,sender=‘org.gnome.TypingMonitor’,interface=‘org.gnome.TypingMonitor’”
Multiple rules can be specified. If a message matches any of the rules, the message will be printed. Like so:
dbus-monitor “type=error” “sender=org.freedesktop.SystemToolsBackends”
dbus-monitor “type=method_call” “type=method_return” “type=error”
1.5.d-feet
2.configure files
uos@uos-PC:$ vim /etc/dbus-1/system.d/
bluetooth.conf com.deepin.filemanager.daemon.conf dnsmasq.conf nm-openconnect-service.conf org.freedesktop.DisplayManager.conf org.kde.kf5auth.conf
com.deepin.anything.conf com.deepin.license.conf net.hadess.SensorProxy.conf nm-sstp-service.conf org.freedesktop.GeoClue2.Agent.conf org.kubuntu.qaptworker3.conf
com.deepin.devicemanager.conf com.deepin.serviceandsupport.conf net.reactivated.Fprint.conf nm-strongswan-service.conf org.freedesktop.GeoClue2.conf pulseaudio-system.conf
com.deepin.dtk.FileDrag.conf com.hp.hplip.conf nm-l2tp-service.conf org.freedesktop.Accounts.conf org.freedesktop.ModemManager1.conf wpa_supplicant.conf
refer to
- http://just4coding.com/2018/07/31/dbus/
- https://www.freedesktop.org/wiki/IntroductionToDBus/
- https://wiki.ubuntu.com/DebuggingDBus
- https://superuser.com/questions/1082423/dbus-how-can-i-monitor-process
- https://medium.com/cesar-update/exposing-a-d-bus-interface-in-linux-part-1-90e68e754c72