Skip to content

Latest commit

 

History

History
209 lines (161 loc) · 9.74 KB

2017-01-04-getting-started-with-dbus.md

File metadata and controls

209 lines (161 loc) · 9.74 KB
layout title date categories tags excerpt
post
Getting started with D-BUS
2017-01-04 11:00:30 -0800
Linux
dbus
Getting started with D-BUS

Introduction

D-BUS是一种进程间通信(IPC)机制,一般主要用于基于AF_UNIX套接字的本地进程间通信(local IPC)(当然也可以基于TCP/IP)实现跨主机的通信。

Linux上已经存在很多local IPC机制,比如FIFO、UNIX套接字等,为什么还要搞一个D-BUS呢?实际上,D-BUS采用了RPC(Remote Procedure Calling)的思想,它相当于本机的RPC,RPC相对于原始的FIFO、unix socket,是更加现代的通信方式,RPC框架本身会负责消息的编解码、安全验证等。这些会大大简化应用程序的开发。

D-Bus包含下面一些内容:

(1) libdbus: a low-level library

(2) dbus-daemon: a daemon based on libdbus. Handles and controls data transfers between DBus peers

(3) two types of busses: a system and a session one. Each bus instance is managed by a dbus-daemon

(4) a security mechanism using policy files

值得一提的是systemd没有使用libdbus,而是使用自己实现的library。

D-Bus Concepts

D-BUS协议是一个端到端(peer-to-peer or client-server)的通信协议,它包含一些基本的概念

  • 总线(bus)

相当于D-BUS的通信链路,应用之间通过总线进行通信。应用在总线上寻找service。有两种总线:

A "system bus" for notifications from the system to user sessions, and to allow the system to request input from user sessions.

A "session bus" used to implement desktop environments such as GNOME and KDE.

  • 服务(service)

服务是提供IPC API的程序,每个服务都有一个reverse domain name结构的标识名称。比如org.freedesktop.NetworkManager对应系统总线上的NetworkManagerorg.freedesktop.login1对应系统总线上的systemd-logind

  • 对象(object)

相当于通信的地址,每个serviceobject都通过object path来标识,object path类似文件系统的路径。比如/org/freedesktop/login1是服务org.freedesktop.login1manager对象的路径。

  • 接口(interfaces)

每个object包含一个或者多个interfaces。D-Bus interfaces define the methods and signals supported by D-Bus objects。

  • 方法(method)

D-Bus methods may accept any number of arguments and may return any number of values, including none.

  • signal

D-Bus signals provide a 1-to-many, publish-subscribe mechanism. Similar to method return values, D-Bus signals may contain an arbitrary ammount of data. Unlike methods however, signals are entirely asynchronous and may be emitted by D-Bus objects at any time.

  • signature

signature用于描述参数的数据类型,比如s代表UTF-8字符串。

更多概念参考DBus Overview

From shell

有一些D-BUS相关的工具,比如busctlgdbusdbus-send等,通过这些工具可以进行一些D-BUS相关的操作。

列出所有连接系统总线的端点:

# busctl
NAME                                   PID PROCESS         USER             CONNECTION    UNIT                      SESSION    DESCR
:1.0                                     1 systemd         root             :1.0          init.scope                -          -    
:1.1                                   516 polkitd         polkitd          :1.1          polkit.service            -          -    
:1.10                                 1305 busctl          root             :1.10         sshd.service              -          -    
:1.2                                   719 tuned           root             :1.2          tuned.service             -          -    
com.redhat.tuned                       719 tuned           root             :1.2          tuned.service             -          -    
fi.epitest.hostap.WPASupplicant          - -               -                (activatable) -                         -         
fi.w1.wpa_supplicant1                    - -               -                (activatable) -                         -         
org.freedesktop.DBus                     - -               -                -             -                         -          -    
org.freedesktop.PolicyKit1             516 polkitd         polkitd          :1.1          polkit.service            -          -    
org.freedesktop.hostname1                - -               -                (activatable) -                         -         
org.freedesktop.import1                  - -               -                (activatable) -                         -         
org.freedesktop.locale1                  - -               -                (activatable) -                         -         
org.freedesktop.login1                   - -               -                (activatable) -                         -         
org.freedesktop.machine1                 - -               -                (activatable) -                         -         
org.freedesktop.network1                 - -               -                (activatable) -                         -         
org.freedesktop.resolve1                 - -               -                (activatable) -                         -         
org.freedesktop.systemd1                 1 systemd         root             :1.0          init.scope                -          -    
org.freedesktop.timedate1                - -               -                (activatable) -                         -         

D-Bus API of systemd

systemd提供了一些D-BUS API,通过API,我们可以进行systemd的各种操作,比如启动、停止服务等。

查看所有的API:

# gdbus introspect --system --dest org.freedesktop.systemd1 --object-path /org/freedesktop/systemd1
node /org/freedesktop/systemd1 {
  interface org.freedesktop.DBus.Peer {
    methods:
      Ping();
      GetMachineId(out s machine_uuid);
    signals:
    properties:
  };
  interface org.freedesktop.DBus.Introspectable {
    methods:
      Introspect(out s data);
    signals:
    properties:
  };
  interface org.freedesktop.DBus.Properties {
    methods:
      Get(in  s interface,
          in  s property,
          out v value);
      GetAll(in  s interface,
             out a{sv} properties);
      Set(in  s interface,
          in  s property,
          in  v value);
    signals:
      PropertiesChanged(s interface,
                        a{sv} changed_properties,
                        as invalidated_properties);
    properties:
  };
  interface org.freedesktop.systemd1.Manager {
    methods:
      GetUnit(in  s arg_0,
              out o arg_1);
      GetUnitByPID(in  u arg_0,
                   out o arg_1);
      LoadUnit(in  s arg_0,
               out o arg_1);
      StartUnit(in  s arg_0,
                in  s arg_1,
                out o arg_2);
      StartUnitReplace(in  s arg_0,
                       in  s arg_1,
                       in  s arg_2,
                       out o arg_3);
      StopUnit(in  s arg_0,
               in  s arg_1,
               out o arg_2);
      ReloadUnit(in  s arg_0,
                 in  s arg_1,
                 out o arg_2);
      RestartUnit(in  s arg_0,
                  in  s arg_1,
                  out o arg_2);
...

接口org.freedesktop.systemd1.Manager包含了systemd提供的主要操作方法。

  • StartUnit/StopUnit
# busctl --system call org.freedesktop.systemd1 /org/freedesktop/systemd1 org.freedesktop.systemd1.Manager GetUnit s crond.service 
o "/org/freedesktop/systemd1/unit/crond_2eservice"


# busctl --system call org.freedesktop.systemd1 /org/freedesktop/systemd1 org.freedesktop.systemd1.Manager StopUnit ss crond.service replace
o "/org/freedesktop/systemd1/job/904"

# systemctl status crond.service
● crond.service - Command Scheduler
   Loaded: loaded (/usr/lib/systemd/system/crond.service; enabled; vendor preset: enabled)
   Active: inactive (dead) since 四 2017-01-05 03:13:29 CST; 4s ago
  Process: 656 ExecStart=/usr/sbin/crond -n $CRONDARGS (code=exited, status=0/SUCCESS)
 Main PID: 656 (code=exited, status=0/SUCCESS)
...

# busctl --system call org.freedesktop.systemd1 /org/freedesktop/systemd1 org.freedesktop.systemd1.Manager StartUnit ss crond.service replace
o "/org/freedesktop/systemd1/job/905"

# systemctl status crond.service
● crond.service - Command Scheduler
   Loaded: loaded (/usr/lib/systemd/system/crond.service; enabled; vendor preset: enabled)
   Active: active (running) since 四 2017-01-05 03:13:53 CST; 1s ago
 Main PID: 12277 (crond)
   Memory: 624.0K
   CGroup: /system.slice/crond.service
           └─12277 /usr/sbin/crond -n
...

Reference