DBus daemon 启动(三)

本文详细介绍了DBus消息总线守护进程的启动方式及其配置方法,包括dbus-daemon的常用命令参数解析,以及如何通过不同的参数组合来启动system或session实例。

前面简单了解一下,DBus的架构和简单的应用编程.那么接下来,就来看看,DBus是怎么启动的,这一往篇不涉及内部实现问题,只是介绍dbus-daemon如何启动及涉及哪里配置


一.编译Dbus库完成之后,包含:
可执行文件: dbus-daemon, dbus-launch, dbus-send, dbus-monitor, dbus-cleanup-sockets, dbus-run-session, dbus-test-tool,dbus-update-activation-environment, dbus-uuidgen.这里面最常用的就是dbus-daemon,不然dbus不能使用.其他先不做了解,目前只会用到dbus-daemon.
库文件:libdbus-1.a, libdbus-1.la, libdbus-1.so.3.13.0生成这三个库,包含的就是咱们应用编程接口.比如dbus_bus_get()


二.dbus-daemon
->dbus-deamon是一个D-Bus消息总线daemon,跑在后台,它支持两个应用进程间一对一的通信,dbus-deamon也是用上面的库实现的
->系统启动之后,有两个dbus daemon的实例, 一个称为system, 一个称为session(如果是多个用户,那么会每个用户启动一个),这个实例配置不同,权限也不同
->system 实例使用的配置文件=/etc/dbus-1/system.conf
->session实例使用的配置文件=/etc/dbus-1/session.conf
->一般来说system实例,被init script启动,所以具有root权根.大部分功能用于广播系统事件,比如插拨设备.
->session daemon用于不同桌面的进程通信或不同进程间的通信.
->SIGHUP 信号导致dbus-daemon重新去加载配置,如果你改变配置之后,就需要发信号给dbus-daemon,让其去重新加载配置.


三. dbus-daemon 命令参数
june@june:~$ dbus-daemon -h
dbus-daemon [--version] [--session] [--system] [--config-file=FILE] [--print-address[=DESCRIPTOR]] [--print-pid[=DESCRIPTOR]] [--fork] [--nofork] [--introspect] [--address=ADDRESS] [--systemd-activation] [--nopidfile]


[这些设置选项优先级大于配置文件所配置的]
--session                          针对每个登录用户,普通用户(普通权限的dbus daemon)
--system                          针对系统用户,超级权限(有特权的dbus daemon)
--config-file=FILE            指定dbus daemon相关配置文件位置
--fork                               让dbus daemon变为一个daemon
--nofork                        --fork的反操作
--print-address[=DESCRIPTOR]          打印出dbus daemon监听地址.
--print-pid[=DESCRIPTOR]                 打印出dbus daemon pid
--introspect                      打印出dbus daemon内部实现的方法
--address                          设置监听地址
--nopidfile                        不写pid 到文件(配置文件会配置一个文件来记录dbus daemon pid)
--systemd-activation        可能跟systemd启动服务有关,没做研究.
--syslog                             强制dbus daemon 用syslog(即会记录log,也会输出到标准输出)
--syslog-only                     仅做 syslog
--nosyslog                         仅做标准输出


------>这些是dbus daemon的一些配置
举一些例子:

1.dbus-daemon --session --print-address  --nofork --print-pid

(结果就是开启dbus-daemon session类型, 打印出监听地址,打印出pid, 且不做fork(意味着不是一个daemon))

	root@june:~# dbus-daemon --session --print-address --nofork --print-pid
	unix:abstract=/tmp/dbus-ylwBCGyhmF,guid=bd7496f59ac6455852a455b45b398e03
	6943

2.dbus-daemon --session --print-address --fork --print-pid 

 

(这个与1不同的是,做fork,变为一个daemon)

 

	root@june:~# dbus-daemon --session --print-address --fork --print-pid
	unix:abstract=/tmp/dbus-01B2SkM7sU,guid=8457d8efbb98cfd3fc6488c15b398e81
	6946
	root@june:

3.dbus-daemon --session --print-address --fork --print-pid --introspect

 

(打印出dbus daemon内部所有的方法)

 

root@june:~# dbus-daemon --session --print-address --fork --print-pid --introspect
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
  <interface name="org.freedesktop.DBus">
    <method name="Hello">
      <arg direction="out" type="s"/>
    </method>
    <method name="RequestName">
      <arg direction="in" type="s"/>
      <arg direction="in" type="u"/>
      <arg direction="out" type="u"/>
    </method>
    <method name="ReleaseName">
      <arg direction="in" type="s"/>
      <arg direction="out" type="u"/>
    </method>
    <method name="StartServiceByName">
      <arg direction="in" type="s"/>
      <arg direction="in" type="u"/>
      <arg direction="out" type="u"/>
    </method>
    <method name="UpdateActivationEnvironment">
      <arg direction="in" type="a{ss}"/>
    </method>
    <method name="NameHasOwner">
      <arg direction="in" type="s"/>
      <arg direction="out" type="b"/>
    </method>
    <method name="ListNames">
      <arg direction="out" type="as"/>
    </method>
    <method name="ListActivatableNames">
      <arg direction="out" type="as"/>
    </method>
    <method name="AddMatch">
      <arg direction="in" type="s"/>
    </method>
    <method name="RemoveMatch">
      <arg direction="in" type="s"/>
    </method>
    <method name="GetNameOwner">
      <arg direction="in" type="s"/>
      <arg direction="out" type="s"/>
    </method>
    <method name="ListQueuedOwners">
      <arg direction="in" type="s"/>
      <arg direction="out" type="as"/>
    </method>
    <method name="GetConnectionUnixUser">
      <arg direction="in" type="s"/>
      <arg direction="out" type="u"/>
    </method>
    <method name="GetConnectionUnixProcessID">
      <arg direction="in" type="s"/>
      <arg direction="out" type="u"/>
    </method>
    <method name="GetAdtAuditSessionData">
      <arg direction="in" type="s"/>
      <arg direction="out" type="ay"/>
    </method>
    <method name="GetConnectionSELinuxSecurityContext">
      <arg direction="in" type="s"/>
      <arg direction="out" type="ay"/>
    </method>
    <method name="GetConnectionAppArmorSecurityContext">
      <arg direction="in" type="s"/>
      <arg direction="out" type="s"/>
    </method>
    <method name="ReloadConfig">
    </method>
    <method name="GetId">
      <arg direction="out" type="s"/>
    </method>
    <signal name="NameOwnerChanged">
      <arg type="s"/>
      <arg type="s"/>
      <arg type="s"/>
    </signal>
    <signal name="NameLost">
      <arg type="s"/>
    </signal>
    <signal name="NameAcquired">
      <arg type="s"/>
    </signal>
  </interface>
  <interface name="org.freedesktop.DBus.Introspectable">
    <method name="Introspect">
      <arg direction="out" type="s"/>
    </method>
  </interface>
</node>

在dbus相关编程中就有dbus_bus_request_name()接口调用,那么这个就是调用的这个列表的接口.

4. dbus-daemon --session --print-address --fork --print-pid --address=unix:abstract=/tmp/dbus-123456

(指定一个监听地址)

root@june:~# dbus-daemon --session --print-address --fork --print-pid --address=unix:abstract=/tmp/dbus-123456
unix:abstract=/tmp/dbus-123456,guid=aa09ca517dbda223d9c7657a5b398fa8
6954
root@june:~# 

----->这里说明的是,如何启动dbus-daemon,  还有一点就是,为什么上面没有设置关于--config-file问题,--config-file默认是/etc/dbus-1/[system|session].conf,下面了解配置里面有都有什么.

<think>我们正在分析 dbus 启动失败的原因及解决方案。根据用户提供的引用和之前的历史记录,我们可以总结出以下几个常见原因和对应的解决方案: 常见原因: 1. **配置文件错误**:dbus 的服务配置文件(如 dbus.service)中可能存在路径错误、语法错误或权限问题。 2. **路径问题**:可执行文件的路径不是绝对路径(如之前出现的错误:`Executable path is not absolute`)。 3. **文件行尾格式问题**:在从Windows系统克隆代码到Linux时,脚本文件的行尾格式可能是Windows格式(CRLF)导致在Linux下无法执行。 4. **依赖问题**:dbus 依赖的其他服务没有启动配置错误。 5. **权限问题**:运行dbus服务的用户没有足够的权限。 6. **环境变量问题**:如DBUS_SESSION_BUS_ADDRESS等环境变量设置不正确。 7. **版本冲突**:系统中安装了多个版本的dbus,或者库文件版本不匹配(如引用[3]中的问题)。 解决方案: 1. **检查 dbus 服务状态**: 使用命令 `systemctl status dbus.service` 查看当前状态和错误信息。 2. **检查配置文件**: - 检查dbus的service文件(通常在`/usr/lib/systemd/system/dbus.service`)中的`ExecStart`路径是否为绝对路径,并修正任何错误(如之前提到的去掉路径前的`@`符号)[^1]。 - 确保配置文件中的语法正确,比如每行一个指令,正确的参数等。 3. **检查脚本文件的行尾格式**: 如果是从git克隆的项目,并且是在Windows上克隆然后复制到Linux的,需要检查脚本文件的行尾格式。可以使用`dos2unix`工具转换: ```bash sudo apt-get install dos2unix # 如果没有安装,先安装 find /path/to/dbus/scripts -type f -name "*.sh" -exec dos2unix {} \; ``` 4. **检查依赖关系**: 确保dbus所需的其他服务已经启动。可以使用`systemctl list-dependencies dbus.service`查看依赖。 5. **检查权限问题**: - 确保dbus服务运行时使用的用户(通常是`messagebus`或`dbus`)具有执行所需文件的权限。 - 检查`/var/run/dbus`目录的权限,确保dbus用户有读写权限。 6. **检查环境变量**: 对于会话总线,确保环境变量`DBUS_SESSION_BUS_ADDRESS`正确设置。对于系统总线,通常由systemd管理。 7. **解决库版本冲突**: 如果出现类似引用[3]中的库版本问题,可以检查库文件链接是否正确,或者重新安装dbus以修复库链接。 8. **查看日志**: 使用`journalctl -u dbus.service -xe`查看详细的启动日志,根据日志中的错误信息进行排查。 9. **重新安装dbus**: 如果以上步骤无法解决,可以考虑重新安装dbus: ```bash sudo apt-get install --reinstall dbus ``` 10. **确保dbus系统服务已启用**: 使用`sudo systemctl enable dbus`确保dbus启动时自动运行。 相关问题: 1. 如何检查dbus服务是否正常运行? 2. 除了systemctl status,还有哪些方法可以诊断dbus问题? 3. 如何为dbus服务添加自定义配置? 4. 在容器环境中如何正确配置dbus? 下面我们按照用户要求的结构化格式输出: </think>### DBus 启动失败的原因及解决方案 #### 常见原因分析 1. **配置文件语法错误** - 绝对路径缺失(如 `ExecStart=@/usr/bin/dbus-daemon` 中的 `@` 符号) - 行尾格式问题(Windows CRLF 导致 Linux 无法解析)[^2] - 服务注册路径错误(应为 `/usr/share/dbus-1.0/`)[^2] 2. **权限问题** - 服务运行用户缺少权限(如无法访问 `/var/run/dbus`) - SELinux/AppArmor 安全策略限制[^1] 3. **依赖库冲突** - 版本不匹配(如 `LIBDBUS_1_3 not defined in file libdbus-1.so.3`)[^3] - 多版本共存导致符号冲突 4. **环境变量缺失** - `DBUS_SESSION_BUS_ADDRESS` 未正确设置[^4] - `$DISPLAY` 变量缺失(影响 GUI 相关服务)[^4] 5. **系统资源冲突** - 端口占用(DBus 默认使用 UNIX 域套接字) - 服务死锁或残留进程 --- #### 解决方案指南 ##### 步骤 1:基础排查 ```bash # 检查服务状态和日志 systemctl status dbus.service journalctl -u dbus.service -xe --since "5 minutes ago" # 验证 DBus 守护进程 ps aux | grep dbus-daemon ``` ##### 步骤 2:修复配置文件 1. **修正绝对路径** 编辑服务文件(通常位于 `/usr/lib/systemd/system/dbus.service`): ```ini # 错误示例 ❌ ExecStart=@/usr/bin/dbus-daemon --system # 修正为 ✅ ExecStart=/usr/bin/dbus-daemon --system ``` 2. **转换行尾格式** 使用 `dos2unix` 处理配置脚本: ```bash sudo apt install dos2unix find /etc/dbus-1 -type f -name "*.conf" -exec dos2unix {} \; ``` 3. **验证注册路径** 确保服务文件在正确位置: ```bash sudo cp /path/to/service-file.service /usr/share/dbus-1/system-services/ sudo systemctl daemon-reload ``` ##### 步骤 3:解决权限问题 ```bash # 重置目录权限 sudo chown -R messagebus:messagebus /var/run/dbus sudo chmod 755 /var/run/dbus # 临时禁用安全策略(测试用) sudo setenforce 0 # SELinux sudo apparmor_parser -R /etc/apparmor.d/usr.bin.dbus-daemon # AppArmor ``` ##### 步骤 4:处理依赖冲突 ```bash # 重建库链接 sudo ldconfig # 检查版本兼容性 ldd /usr/bin/dbus-daemon | grep dbus # 重新安装 DBus sudo apt install --reinstall dbus ``` ##### 步骤 5:环境变量修复 ```bash # 手动设置会话总线(适用于用户级服务) eval $(dbus-launch --auto-syntax) # 见引用[4] # 系统级变量配置 echo "export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/dbus/system_bus_socket" >> ~/.bashrc ``` --- #### 进阶诊断工具 | 工具 | 命令示例 | 用途 | |---------------|------------------------------|--------------------------| | `dbus-send` | `dbus-send --system --print-reply --dest=org.freedesktop.DBus / org.freedesktop.DBus.ListNames` | 测试总线连接性 | | `d-feet` | GUI 工具 | 可视化 DBus 服务状态[^2] | | `strace` | `sudo strace -p $(pidof dbus-daemon)` | 跟踪系统调用 | --- #### 关键预防措施 1. **配置审计** 使用 `dbus-update-activation-environment` 验证环境变量 ```bash dbus-update-activation-environment --systemd DBUS_SESSION_BUS_ADDRESS ``` 2. **版本控制** 保持 `dbus` 与依赖库版本一致: ```bash apt show dbus libdbus-1-3 ``` 3. **沙盒测试** 通过 `systemd-nspawn` 容器隔离测试: ```bash sudo systemd-nspawn -D / --boot --bind-ro=/etc/dbus-1 ``` --- #### 相关问题 1. 如何诊断 DBus 服务之间的通信故障? 2. 在容器环境中如何正确配置 DBus? 3. DBus 的安全策略(如 PolicyKit)如何定制? 4. 系统升级后 DBus 服务失效的恢复步骤? > 通过以上方法可解决 90% 的 DBus 启动问题,若仍失败建议提供完整日志: > `journalctl -b 0 -u dbus.service > dbus_failure.log`
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值