原 D-Bus 配置相关(四)

本文深入解析DBus配置文件的结构和作用,包括dbusdaemon的bus类型、资源限制、安全策略等配置项。并通过实例演示如何手动启动DBus守护进程,以及客户端和服务端的通信过程,包括信号发送和方法调用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一个dbus daemon都一个配置文件来指定建立什么类型的dbus daemon,比如sysetm或者session类型,配置文件还会有一些资源限制,安全相关的参数设置等等


一.dbus daemon配置文件
我系统中的session的配置文件选项列出来

地址: /etc/dbus-1/session.conf

配置文件是xml格式

 

june@june:/etc/dbus-1$ cat session.conf 
<!-- This configuration file controls the per-user-login-session message bus.
     Add a session-local.conf and edit that rather than changing this 
     file directly. -->
 
<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-Bus Bus Configuration 1.0//EN"
 "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig> <span style="color:#ff0000;">//root 元素</span>
  <!-- Our well-known bus type, don't change this -->
  <type>session</type>    <span style="color:#ff0000;">//dbus daemon bus类型(session or system)</span>
 
  <!-- If we fork, keep the user's original umask to avoid affecting
       the behavior of child processes. -->
  <keep_umask/>     <span style="color:#ff0000;">// 如果设置了--fork,或者<fork>, 父子进程mask保持一致</span>
 
  <listen>unix:tmpdir=/tmp</listen>    <span style="color:#ff0000;">//设置监听地址,与命令--address一样功能</span>
 
  <standard_session_servicedirs />   <span style="color:#ff0000;">//标准的dbus service目录,就是一些按需启动的一些服务,</span>
                                        <span style="color:#ff0000;">//添加在这个目录,在linux系统中目录/usr/share/dbus-1/service</span>
  <policy context="default">            <span style="color:#ff0000;">//设置一些全制策略</span>
    <allow own="*"/>                    <span style="color:#ff0000;">//允许所有own</span>
    <!-- Allow everything to be sent -->   
    <allow send_destination="*" eavesdrop="true"/> <span style="color:#ff0000;"> //发送</span>
    <!-- Allow everything to be received -->        
    <allow eavesdrop="true"/>                        <span style="color:#ff0000;">//接收</span>
    <!-- Allow anyone to own anything -->
    <allow own="*"/>
    
    <span style="color:#ff0000;">//这个是我手动添加的,无关紧要,就是为了体现配置, 允许所有类型的消息,dbus消息类型公有以下四种.</span>
    <!-- All messages may be received by default -->
    <allow receive_type="method_call"/>
    <allow receive_type="method_return"/>
    <allow receive_type="error"/>
    <allow receive_type="signal"/>
  </policy>
 
 
  <!-- raise the service start timeout to 40 seconds as it can timeout
       on the live cd on slow machines -->
  <limit name="service_start_timeout">60000</limit>
 
 
  <!-- Config files are placed here that among other things, 
       further restrict the above policy for specific services. -->
  <includedir>session.d</includedir>    <span style="color:#ff0000;">//这个指定目录,就是为添加配置所用,如果你想添加配置,即可在seesion.con添加</span>
//root 元素
  <!-- Our well-known bus type, don't change this -->
  <type>session</type>    //dbus daemon bus类型(session or system)

  <!-- If we fork, keep the user's original umask to avoid affecting
       the behavior of child processes. -->
  <keep_umask/>     // 如果设置了--fork,或者<fork>, 父子进程mask保持一致

  <listen>unix:tmpdir=/tmp</listen>    //设置监听地址,与命令--address一样功能

  <standard_session_servicedirs />   //标准的dbus service目录,就是一些按需启动的一些服务,
                                        //添加在这个目录,在linux系统中目录/usr/share/dbus-1/service
  <policy context="default">            //设置一些全制策略
    <allow own="*"/>                    //允许所有own
    <!-- Allow everything to be sent -->   
    <allow send_destination="*" eavesdrop="true"/>  //发送
    <!-- Allow everything to be received -->        
    <allow eavesdrop="true"/>                        //接收
    <!-- Allow anyone to own anything -->
    <allow own="*"/>
    
    //这个是我手动添加的,无关紧要,就是为了体现配置, 允许所有类型的消息,dbus消息类型公有以下四种.
    <!-- All messages may be received by default -->
    <allow receive_type="method_call"/>
    <allow receive_type="method_return"/>
    <allow receive_type="error"/>
    <allow receive_type="signal"/>
  </policy>


  <!-- raise the service start timeout to 40 seconds as it can timeout
       on the live cd on slow machines -->
  <limit name="service_start_timeout">60000</limit>


  <!-- Config files are placed here that among other things, 
       further restrict the above policy for specific services. -->
  <includedir>session.d</includedir>    //这个指定目录,就是为添加配置所用,如果你想添加配置,即可在seesion.con添加

//root 元素
  <!-- Our well-known bus type, don't change this -->
  <type>session</type>    //dbus daemon bus类型(session or system)

  <!-- If we fork, keep the user's original umask to avoid affecting
       the behavior of child processes. -->
  <keep_umask/>     // 如果设置了--fork,或者<fork>, 父子进程mask保持一致

  <listen>unix:tmpdir=/tmp</listen>    //设置监听地址,与命令--address一样功能

  <standard_session_servicedirs />   //标准的dbus service目录,就是一些按需启动的一些服务,
                                        //添加在这个目录,在linux系统中目录/usr/share/dbus-1/service
  <policy context="default">            //设置一些全制策略
    <allow own="*"/>                    //允许所有own
    <!-- Allow everything to be sent -->   
    <allow send_destination="*" eavesdrop="true"/>  //发送
    <!-- Allow everything to be received -->        
    <allow eavesdrop="true"/>                        //接收
    <!-- Allow anyone to own anything -->
    <allow own="*"/>
    
    //这个是我手动添加的,无关紧要,就是为了体现配置, 允许所有类型的消息,dbus消息类型公有以下四种.
    <!-- All messages may be received by default -->
    <allow receive_type="method_call"/>
    <allow receive_type="method_return"/>
    <allow receive_type="error"/>
    <allow receive_type="signal"/>
  </policy>


  <!-- raise the service start timeout to 40 seconds as it can timeout
       on the live cd on slow machines -->
  <limit name="service_start_timeout">60000</limit>


  <!-- Config files are placed here that among other things, 
       further restrict the above policy for specific services. -->
  <includedir>session.d</includedir>    //这个指定目录,就是为添加配置所用,如果你想添加配置,即可在seesion.con添加
 

                                      <span style="color:#ff0000;">//也可以在这个目录下添加,建议在此,可以模块化管理,添加的文件必须以.conf结尾,否则不识别</span>
//也可以在这个目录下添加,建议在此,可以模块化管理,添加的文件必须以.conf结尾,否则不识别

 

//也可以在这个目录下添加,建议在此,可以模块化管理,添加的文件必须以.conf结尾,否则不识别
  <!-- This is included last so local configuration can override what's 
       in this standard file -->
  <include ignore_missing="yes">session-local.conf</include> //session 配置文件,如果没有就跳过,不报错
                                                              //如果ignore_missing="no", 配置文件不存在,会报错.

  <include if_selinux_enabled="yes" selinux_root_relative="yes">contexts/dbus_contexts</include> //安全相关的配置,类似与防火墙


  <!-- For the session bus, override the default relatively-low limits 
       with essentially infinite limits, since the bus is just running 
       as the user anyway, using up bus resources is not something we need 
       to worry about. In some cases, we do set the limits lower than 
       "all available memory" if exceeding the limit is almost certainly a bug, 
       having the bus enforce a limit is nicer than a huge memory leak. But the 
       intent is that these limits should never be hit. -->

    //下面这些是资源的一些限制
  <!-- the memory limits are 1G instead of say 4G because they can't exceed 32-bit signed int max -->
  <limit name="max_incoming_bytes">1000000000</limit>
  <limit name="max_incoming_unix_fds">250000000</limit>
  <limit name="max_outgoing_bytes">1000000000</limit>
  <limit name="max_outgoing_unix_fds">250000000</limit>
  <limit name="max_message_size">1000000000</limit>
  <!-- We do not override max_message_unix_fds here since the in-kernel
       limit is also relatively low -->
  <limit name="service_start_timeout">120000</limit>  
  <limit name="auth_timeout">240000</limit>
  <limit name="pending_fd_timeout">150000</limit>
  <limit name="max_completed_connections">100000</limit>  
  <limit name="max_incomplete_connections">10000</limit>
  <limit name="max_connections_per_user">100000</limit>
  <limit name="max_pending_service_starts">10000</limit>
  <limit name="max_names_per_connection">50000</limit>
  <limit name="max_match_rules_per_connection">50000</limit>
  <limit name="max_replies_per_connection">50000</limit>
</busconfig>

下面举例测试一些规则:
前提条件: 1.在自己电脑上安装好dbus,一般不用装,系统与ui交互都需要D-Bus

                2. 拷贝 DBus 实例 中的代码,然后编译
(最好看一下源代码的逻辑,做了什么,这样更有利于理解)
 

一.源代码编译:

june@june:~/document/comb$ gcc service.c -ldbus-1 -I/usr/include/dbus-1.0 -o service
june@june:~/document/comb$ 
june@june:~/document/comb$ gcc client.c -ldbus-1 -I/usr/include/dbus-1.0 -o client
june@june:~/document/comb$ ls
client  client.c  service  service.c
june@june:~/document/comb$ 

二.手动启动一个Dbus daemon

june@june:~/document/comb$ dbus-daemon --session --print-address --fork --print-pid
unix:abstract=/tmp/dbus-CSy0dphkTM,guid=24e009e82bece7928f58cc4b5b39c4f6
2900
june@june:~/document/comb$ 

三.关键的一步,需要把监听的address export出来(为什么要这么做呢,因为dbus_bus_get()获取连接的时候,会去找这个环境变量,来获取监听地址)

june@june:~/document/comb$ export  DBUS_SESSION_BUS_ADDRESS=unix:abstract=/tmp/dbus-CSy0dphkTM,guid=24e009e82bece7928f58cc4b5b39c4f6
june@june:~/document/comb$ 

四.运行,测试结果

june@june:~/document/comb$ ./service &       <span style="color:#ff0000;"> //放在后台做服务端</span>
[1] 2903
june@june:~/document/comb$ path: /org/freedesktop/DBus
path: /org/freedesktop/DBus
 
june@june:~/document/comb$ ./client       <span style="color:#ff0000;"> //在前台运行,做请求端,client共做了两件事:</span>
path: /org/freedesktop/DBus               <span style="color:#ff0000;"> //1. 发信号到 path=/hello interface=aa.bb.cc signal=alarm_test 且携带的信号内容为hello world!</span>
path: /org/freedesktop/DBus                <span style="color:#ff0000;">//2.调用add操作到bus name=hello.world.service path=/hello/world interface=hello.world method =add</span>
path: /hello                                <span style="color:#ff0000;">//? 为什么signal没有指定bus name呢,因为signal是广播,不过也有接口可以指定目的bus name的,那样就变为单播了</span>.
recv param --: <span style="color:#ff0000;">hello world!</span>
path: /hello/world
service: add  function
<span style="color:#ff0000;"> a(100) + b(99) = 199</span>
june@june:~/document/comb$
 //放在后台做服务端
[1] 2903
june@june:~/document/comb$ path: /org/freedesktop/DBus
path: /org/freedesktop/DBus

june@june:~/document/comb$ ./client        //在前台运行,做请求端,client共做了两件事:
path: /org/freedesktop/DBus                //1. 发信号到 path=/hello interface=aa.bb.cc signal=alarm_test 且携带的信号内容为hello world!
path: /org/freedesktop/DBus                //2.调用add操作到bus name=hello.world.service path=/hello/world interface=hello.world method =add
path: /hello                                //? 为什么signal没有指定bus name呢,因为signal是广播,不过也有接口可以指定目的bus name的,那样就变为单播了.
recv param --: hello world!
path: /hello/world
service: add  function
 a(100) + b(99) = 199
june@june:~/document/comb$

 //放在后台做服务端
[1] 2903
june@june:~/document/comb$ path: /org/freedesktop/DBus
path: /org/freedesktop/DBus

june@june:~/document/comb$ ./client        //在前台运行,做请求端,client共做了两件事:
path: /org/freedesktop/DBus                //1. 发信号到 path=/hello interface=aa.bb.cc signal=alarm_test 且携带的信号内容为hello world!
path: /org/freedesktop/DBus                //2.调用add操作到bus name=hello.world.service path=/hello/world interface=hello.world method =add
path: /hello  //? 为什么signal没有指定bus name呢,因为signal是广播,不过也有接口可以指定目的bus name的,那样就变为单播了.
recv param --: hello world!
path: /hello/world
service: add  function
 a(100) + b(99) = 199

五.添加一个安全策略,禁止发送到特定的目的bus name

编写/etc/dbus-1/session.conf

   </policy>上面一行添加<deny send_destination="hello.world.service"/> 禁止发送消息hello.world.service

发送SIGHUP信号到dbus-daemon,可以其重新加载配置 ,在DBus daemon 启动中提到过

在这里禁止发送消息到hello.world.service,那不管是signal还是method都将失败.
 

 

june@june:~/document/comb$ kill -1 2900
june@june:~/document/comb$ ps
  PID TTY          TIME CMD
 2305 pts/0    00:00:00 bash
 2965 pts/0    00:00:00 service
 2979 pts/0    00:00:00 ps
june@june:~/document/comb$ ./client
paramter type error
 a(100) + b(99) = 159115060
june@june:~/document/comb$

如果想看spec文档,请访问:spec文档网址

<think>好的,我现在需要解决用户在WSL的CentOS7镜像中运行systemctl start docker时出现的“Failed to get D-Bus connection: Operation not permitted”错误。根据用户提供的引用和之前的回答,我需要综合这些信息来给出有效的解决方案。 首先,用户提到他们在WSL中安装了CentOS7,并尝试启动docker服务时遇到了问题。引用1和2指出在Docker容器中使用systemctl时会出现类似的错误,而引用3和4分别提到了在单节点和集群模式下的解决方法,以及替换systemctl文件的方案。用户现在是在WSL环境中,这可能与容器环境有所不同,但问题可能相似,因为WSL本身有一些限制。 用户之前的问题涉及到安装systemd和dbus时的权限问题,而现在的错误同样涉及D-Bus连接失败。需要结合之前的解决方案和新的引用内容。可能的根本因包括: 1. **WSL不支持systemd**:WSL默认可能没有完全支持systemd,导致服务管理出现问题。 2. **权限问题**:用户权限或文件系统权限不正确,导致D-Bus无法启动。 3. **dbus服务未正确运行**:dbus守护进程未启动或配置错误。 4. **SELinux或其他安全机制**:虽然WSL中可能没有SELinux,但需要确认。 根据引用4,用户尝试过替换systemctl文件,这可能是一种解决方法,但需要验证是否适用于WSL环境。同时,引用3提到了在Docker中使用tmpfs挂载和cgroup卷,这可能对WSL有参考价值,但需要调整。 接下来,我需要考虑用户在WSL中的具体情况。WSL2虽然支持systemd,但可能需要手动启用。用户可能在旧版本的WSL或配置中没有启用systemd。此外,检查dbus相关的目录权限和进程是否正常启动是关键步骤。另外,替换systemctl文件可能绕过问题,但可能带来其他兼容性问题,需要谨慎处理。 可能的解决方案步骤包括: 1. **启用systemd支持**:检查WSL配置,确认是否启用了systemd。 2. **手动启动dbus服务**:确保dbus守护进程正确运行。 3. **调整文件权限和目录结构**:创建必要的运行时目录并设置正确的权限。 4. **使用替代的systemctl脚本**:如引用4所述,替换systemctl文件可能临时解决问题。 5. **检查Docker配置**:确认Docker服务是否正确安装,是否有其他依赖问题。 需要逐步验证这些步骤,并确保每个步骤适用于WSL环境。例如,在WSL中启用systemd可能需要修改wsl.conf文件,而手动启动dbus可能需要特定的初始化脚本。此外,用户可能在安装Docker时没有正确配置其依赖的服务,导致启动失败。 最后,需要总结这些可能性,并给出一个结构化的解决方案,涵盖不同因和对应的解决步骤,同时参考之前的回答中的权限修复和SELinux策略调整,但可能需要调整以适应WSL的限制。</think>#### 一、问题根源定位 根据你的 **WSL + CentOS7 环境**和报错特征,结合引用[^1][^2][^3][^4],核心因可分为以下三类: | **问题类型** | **具体表现** | **验证方法** | |---------------------|-----------------------------------------------------------------------------|-------------------------| | **1. WSL 生限制** | WSL 默认不完整支持 systemd 的 D-Bus 通信架构,导致 systemctl 无法与守护进程交互 | `ps aux | grep dbus` | | **2. systemd 初始化缺陷** | CentOS 镜像未正确配置 systemd 启动流程,缺少必要的 tmpfs/cgroup 挂载 | `mount | grep cgroup` | | **3. Docker 服务依赖冲突** | Docker 服务依赖的 `containerd` 或 `dbus.socket` 未正确激活 | `systemctl list-dependencies docker` | --- #### 二、WSL 专用解决方案(分步骤) --- ##### **方案1:启用 WSL 的 systemd 支持(推荐)** 1. **升级 WSL 至最新版本** ```bash wsl --update # 确保 WSL 2 内核版本 ≥ 5.10.60.1 ``` 2. **配置 WSL 启用 systemd** 创建或编辑 `/etc/wsl.conf`: ```ini [boot] systemd = true ``` 重启 WSL: ```powershell wsl --shutdown && wsl -d CentOS7 ``` 3. **验证 systemd 状态** ```bash systemctl status dbus # 正常应显示 "active (running)" ``` --- ##### **方案2:手动修复 systemd 环境(适用于旧版 WSL)** 1. **挂载必要文件系统** ```bash sudo mount -t tmpfs tmpfs /tmp sudo mount -t tmpfs tmpfs /run sudo mkdir -p /sys/fs/cgroup sudo mount -t cgroup cgroup /sys/fs/cgroup -o ro,nosuid,nodev,noexec ``` 2. **强制启动 dbus 服务** ```bash sudo /usr/bin/dbus-daemon --system --fork # 手动启动 D-Bus 守护进程 sudo systemctl daemon-reexec # 重载 systemd ``` --- ##### **方案3:替换 systemctl 脚本(应急方案)** 1. **备份 systemctl 文件** ```bash sudo mv /usr/bin/systemctl /usr/bin/systemctl.old ``` 2. **下载替代脚本** ```bash sudo curl -L https://github.com/gdraheim/docker-systemctl-replacement/raw/master/files/docker/systemctl.py -o /usr/bin/systemctl sudo chmod +x /usr/bin/systemctl ``` 3. **重启 Docker 服务** ```bash sudo systemctl start docker # 使用替代脚本绕过 D-Bus 依赖 ``` --- #### 三、流程图:问题解决路径 ```plaintext [报错: Failed to get D-Bus connection] ├─ 1. 检查 WSL 版本 → wsl --version │ ├─ 版本过低 → 升级 WSL(方案1) │ └─ 版本支持 → 检查 systemd 状态(方案1步骤3) ├─ 2. 手动挂载 → mount | grep tmpfs │ ├─ 缺少挂载 → 执行方案2步骤1 │ └─ 挂载正常 → 检查 dbus 进程(方案2步骤2) └─ 3. 应急修复 → 执行方案3 ``` --- #### 、引用说明 [^1]: WSL 生支持 systemd 需特定配置,未启用时 Docker 服务无法通过标准 systemd 流程启动。 [^2]: 容器环境下需挂载 `/sys/fs/cgroup` 以模拟完整 Linux 环境,WSL 同样需要类似操作。 [^3]: 替代 `systemctl` 脚本通过 Python 模拟服务管理,绕过 D-Bus 依赖,但可能影响部分功能。 --- #### 五、相关问题 1. 如何在 WSL 2 中永久启用 systemd? 2. 替代 systemctl 脚本的理是什么? 3. Docker 在 WSL 中的网络配置有何特殊注意事项?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值