gdbus使用G_BUS_TYPE_SYSTEM做开机自启服务

我是用我自己在Glib学习(28) gdbus最简单的例子_gdbus 函数回调-CSDN博客中写的例程,运行服务端和客户端都没有问题,这里使用的bus type是G_BUS_TYPE_SESSION,会话模式。

当我把写好的程序配置成systemd自启动的服务时出现了问题。

name_lost_cb() Error: Failed to connect to dbus

在glib函数手册中已经明确写出了这种问题的原因

You are guaranteed that one of the name_acquired_handler and name_lost_handler callbacks will be invoked after calling this function - there are three possible cases:

  • name_lost_handler with a NULL connection (if a connection to the bus can't be made).

  • bus_acquired_handler then name_lost_handler (if the name can't be obtained)

  • bus_acquired_handler then name_acquired_handler (if the name was obtained).

大体意思就是如果无法连接到总线会执行name_lost_handler函数,如果链接到总线,但无法获取名称会执行bus_acquired_handler函数然后执行name_lost_handler函数,如果获得了名称会执行bus_acquired_handler然后name_acquired_handler函数。

上面的错误直接执行的name_lost_handler函数,说明没有链接到总线。

原因是dbus总线有两种

一个持久的系统总线(system bus):
它在引导时就会启动。这个总线由操作系统和后台进程使用,安全性非常好,以使得任意的应用程序不能欺骗系统事件。它是桌面会话和操作系统的通信,这里操作系统一般而言包括内核和系统守护进程。这种通道的最常用的方面就是发送系统消息,比如:插入一个新的存储设备;有新的网络连接;等等。
还将有很多会话总线(session buses):
这些总线当用户登录后启动,属于那个用户私有。它是用户的应用程序用来通信的一个会话总线。同一个桌面会话中两个桌面应用程序的通信,可使得桌面会话作为整体集成在一起以解决进程生命周期的相关问题。这在GNOME和KDE桌面中大量使用。

ps -elf|grep dbus
4 S message+     747       1  0  80   0 -  2280 -      Nov27 ?        00:00:02 @dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation --syslog-only
0 S renz      531384  450150  0  80   0 -  2109 ep_pol Nov28 ?        00:00:00 /usr/bin/dbus-daemon --session --address=systemd: --nofork --nopidfile --systemd-activation --syslog-only
0 S wangyh   1373937 1372467  0  80   0 -  2074 -      08:13 ?        00:00:00 /usr/bin/dbus-daemon --session --address=systemd: --nofork --nopidfile --systemd-activation --syslog-only

上面就是系统中dbus总线的进程,--system 就是系统总线,--session就是会话总线。

我的理解是会话总线需要有会话才能创建对应的会话总线,然后程序才能连接到对应的会话总线上,因为每个会话有不同的会话总线。

所以系统systemd启动的肯定是没有会话总线存在的,或许有配置系统级别的会话总线的方式吧,我在网上没有找到。

所以我就把程序改成了使用系统总线G_BUS_TYPE_SYSTEM。

编译完成后,运行时出现了如下报错:

bus_acquired_cb()
name_lost_cb() Acquired bus name: cn.com.qwe

如上面glib提供的文档,说明现在找到总线了,但是没有成功分配名字。

然后我就开始在网上查找解决办法,但是资料很少,只有两篇问答有相关线索。

linux - sd-bus API,sd_bus_request_name 返回权限被拒绝 - IT工具网 (coder.work)

glib - DBus, failed to obtain systemwide name - Stack Overflow

glib - DBus,未能获得系统范围的名称 - IT工具网 (coder.work)

后两篇是一个,最下面的是第二篇的中文翻译。

这两篇文章中都提到了使用系统总线时需要提供配置文件,于是开始查找系统配置文件如何书写。

dbus-daemon

这是dbus的官方文档,文档中有对配置文件中各个元素的使用方法,有兴趣的可以自己阅读。

我是按照下面这个文章进行的配置。

dbus org.freedesktop.DBus.Error.AccessDenied 错误处理_acquire d-bus service gdbus.error:orgfreedesktop.d-CSDN博客

我是增加了一个.conf文件,和文章中不同的是,根据官方文档描述,这个conf文件应该放在/usr/share/dbus-1/system.d 目录下。

CONFIGURATION FILE
A message bus daemon has a configuration file that specializes it for a particular application. For example, one configuration file might set up the message bus to be a systemwide message bus, while another might set it up to be a per-user-login-session bus.

The configuration file also establishes resource limits, security parameters, and so forth.

The configuration file is not part of any interoperability specification and its backward compatibility is not guaranteed; this document is documentation, not specification.

The standard systemwide and per-session message bus setups are configured in the files "/usr/share/dbus-1/system.conf" and "/usr/share/dbus-1/session.conf". These files normally <include> a system-local.conf or session-local.conf in /etc/dbus-1; you can put local overrides in those files to avoid modifying the primary configuration files.

The standard system bus normally reads additional XML files from /usr/share/dbus-1/system.d. Third-party packages should install the default policies necessary for correct operation into that directory, which has been supported since dbus 1.10 (released in 2015).

The standard system bus normally also reads XML files from /etc/dbus-1/system.d, which should be used by system administrators if they wish to override default policies.

Third-party packages would historically install XML files into /etc/dbus-1/system.d, but this practice is now considered to be deprecated: that directory should be treated as reserved for the system administrator.

配置完成后就正常了

bus_acquired_cb()
name_acquired_cb() Acquired bus name: cn.com.qwe

是否连接成功也可以使用busctl命令查看

busctl
NAME                                   PID PROCESS         USER             CONNECTION    UNIT                      SESSION    DESCRIPTION
:1.0                                   372 avahi-daemon    avahi            :1.0          avahi-daemon.service      -          -
:1.1                                   374 connmand        root             :1.1          connman.service           -          -
:1.2                                   378 systemd-logind  root             :1.2          systemd-logind.service    -          -
:1.22                                  712 MCCS            root             :1.22         MCCS.service              -          -
:1.23                                  720 busctl          root             :1.23         session-c5.scope          c5         -
:1.3                                     1 systemd         root             :1.3          init.scope                -          -
:1.6                                   427 systemd         root             :1.6          user@0.service            -          -
cn.com.faw.mccs                        712 MCCS            root             :1.22         MCCS.service              -          -
fi.epitest.hostap.WPASupplicant          - -               -                (activatable) -                         -
fi.w1.wpa_supplicant1                    - -               -                (activatable) -                         -
net.connman                            374 connmand        root             :1.1          connman.service           -          -
org.freedesktop.Avahi                  372 avahi-daemon    avahi            :1.0          avahi-daemon.service      -          -
org.freedesktop.DBus                     1 systemd         root             -             init.scope                -          -
org.freedesktop.hostname1                - -               -                (activatable) -                         -
org.freedesktop.locale1                  - -               -                (activatable) -                         -
org.freedesktop.login1                 378 systemd-logind  root             :1.2          systemd-logind.service    -          -
org.freedesktop.network1                 - -               -                (activatable) -                         -
org.freedesktop.resolve1                 - -               -                (activatable) -                         -
org.freedesktop.systemd1                 1 systemd         root             :1.3          init.scope                -          -
org.freedesktop.timedate1                - -               -                (activatable) -                         -
org.freedesktop.timesync1                - -               -                (activatable) -                         -

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值