适用场景:Debian 12 GNOME 桌面,点击”设置”(Settings)
后图标转圈约半分钟才打开,甚至完全打不开。
本文记录一次完整的排查过程:根源不是 GNOME 本身,而是 upower / ModemManager 两个系统服务的 systemd
沙箱配置与 GLib D-Bus 初始化冲突,导致 D-Bus 激活反复超时。
问题现象
gnome-control-center 启动时要通过 D-Bus 连接 org.freedesktop.UPower 和
org.freedesktop.ModemManager1。这两个服务因 unit 文件中的 ProtectHome=true(upower
还叠加 PrivateUsers=yes)启动后立即退出,D-Bus 激活每次等待 25
秒超时,于是设置界面转圈 30~50 秒。给两个服务加 systemd override 关闭沙箱选项后立即秒开。
系统环境
| 组件 | 版本 |
|---|---|
| 操作系统 | Debian 12.15 (bookworm) |
| 内核 | 6.1.0-51-amd64 |
| 桌面 | GNOME Shell 43.9 |
| gnome-control-center | 1:43.6-2~deb12u1 |
| GLib | 2.74.6-2+deb12u9 |
| systemd | 252.39-1~deb12u2 |
| upower | 0.99.20-2 |
| modemmanager | 1.20.4-1 |
症状
- 点击 GNOME”设置”,图标转圈 30~50 秒才打开,严重时完全打不开
- 终端前台运行
gnome-control-center无任何输出、一直挂起 - 日志中反复出现 D-Bus 激活超时:
gnome-control-c[...]: Couldn't connect to proxy: Error calling
StartServiceByName
for org.freedesktop.UPower: Failed to activate service 'org.freedesktop.UPower':
timed out (service_start_timeout=25000ms)
gnome-control-c[...]: Error connecting to ModemManager: Error calling StartServiceByName
for org.freedesktop.ModemManager1: Timeout was reached
排查过程
1 定位到 upower 服务异常
systemctl status upower
# Active: inactive (dead) —— 服务启动后立刻退出
sudo journalctl -u upower -b --no-pager
upowerd[...]: g_dbus_proxy_get_connection: assertion 'G_IS_DBUS_PROXY (proxy)'
failed
upowerd[...]: g_dbus_connection_signal_subscribe: assertion 'G_IS_DBUS_CONNECTION (connection)' failed
upowerd[...]: Could not acquire inhibitor lock: Unknown reason
systemd[1]: upower.service: Deactivated successfully.
upowerd 启动后无法创建到 logind 的 D-Bus 代理对象,申请 inhibitor lock 失败,随即退出。D-Bus 激活方(gnome-control-center、gsd-power)只能等 25 秒超时。
2 手动运行正常,锁定 systemd 沙箱
# 手动前台运行:完全正常,能拿到 inhibitor lock
sudo /usr/libexec/upowerd -v
# TI:13:21:41 Acquired inhibitor lock (7, delay) ← 正常
说明二进制和 GLib 库都没问题,差异只在 systemd unit 的运行环境。检查 unit
文件(/lib/systemd/system/upower.service),发现 Debian 12 自带了一整套安全沙箱选项:
ProtectSystem=strict
ProtectHome=true ← 嫌疑
PrivateUsers=yes ← 嫌疑
PrivateTmp=true
IPAddressDeny=any
RestrictAddressFamilies=AF_UNIX AF_NETLINK
CapabilityBoundingSet=
SystemCallFilter=@system-service
...
3 用 systemd-run 二分定位罪魁祸首
不改动真实服务,用 systemd-run 按选项分组做对照实验:
# 无沙箱:正常
sudo systemd-run --wait --pipe --collect /usr/libexec/upowerd -v
# 系统调用/网络限制组:正常
sudo systemd-run --wait --pipe --collect \
-p SystemCallFilter=@system-service \
-p RestrictAddressFamilies="AF_UNIX AF_NETLINK" -p IPAddressDeny=any \
/usr/libexec/upowerd -v
# 权限/能力限制组:正常
sudo systemd-run --wait --pipe --collect \
-p CapabilityBoundingSet= -p NoNewPrivileges=true \
-p MemoryDenyWriteExecute=true -p LockPersonality=yes \
-p RestrictRealtime=true -p RestrictNamespaces=yes \
/usr/libexec/upowerd -v
# 文件系统组:复现故障!
sudo systemd-run --wait --pipe --collect \
-p ProtectSystem=strict -p ProtectHome=true \
-p PrivateTmp=true -p ProtectKernelModules=true \
/usr/libexec/upowerd -v
# 单选项确认:ProtectHome=true 单独即可复现
sudo systemd-run --wait --pipe --collect -p ProtectHome=true /usr/libexec/upowerd -v
# Could not acquire inhibitor lock: Unknown reason ← 复现
判定标准:看输出第一行,Acquired inhibitor lock 为正常,Could not acquire inhibitor
lock 为复现。
解决方法
1 修复 upower
创建 systemd override,关闭 ProtectHome 和 PrivateUsers(其余沙箱保留):
sudo mkdir -p /etc/systemd/system/upower.service.d
echo -e "[Service]\nProtectHome=false\nPrivateUsers=no" | \
sudo tee /etc/systemd/system/upower.service.d/override.conf
sudo systemctl daemon-reload
sudo systemctl restart upower
systemctl status upower --no-pager | head -6
确认显示 Active: active (running)。
2 修复 ModemManager
upower 修好后 Settings 仍然慢,日志显示第二个超时源是 ModemManager——它的 unit 同样带
ProtectHome=true,同样启动即退:
sudo mkdir -p /etc/systemd/system/ModemManager.service.d
echo -e "[Service]\nProtectHome=false" | \
sudo tee /etc/systemd/system/ModemManager.service.d/override.conf
sudo systemctl daemon-reload
sudo systemctl restart ModemManager
如果台式机确认没有调制解调器 / LTE 模块,也可以直接禁用更干净:
sudo systemctl mask ModemManager
3 验证
systemctl is-active upower ModemManager
# active
# active
重新打开 GNOME 设置:秒开。日志中不再出现 StartServiceByName ... timed out。
注意事项
- 持久化:override 文件位于
/etc/systemd/system/*.d/override.conf,重启后自动生效,无需其他操作。 - 排查陷阱:调试时若用
systemd-run手动起过 upowerd 且没有 Ctrl+C
结束,残留实例会占用org.freedesktop.UPower
总线名,导致真实服务启动后”名字被抢”退出。检查方法:busctl --system list | grep -i,清理:
upowersudo systemctl stop run-uXXX.service。 - 不需要升级 GLib / GNOME:问题与版本无关,Debian stable 混装新版库反而引入风险。
- 连带修复:upower 恢复后,
gsd-power
每分钟崩溃重启(SEGV)的问题也一并消失。
原理小结
点击"设置"
│
▼
gnome-control-center 请求 org.freedesktop.UPower / ModemManager1
│
▼
D-Bus 激活 → systemd 启动服务(带 ProtectHome=true 沙箱)
│
▼
守护进程 D-Bus 代理初始化失败 → 立即退出
│
▼
激活方干等 25 秒超时(多个服务叠加 = 转圈 30~50 秒)
ProtectHome=true 会把 /home 挂载为不可访问。upower 0.99.x / ModemManager 1.20
在该沙箱下初始化 GLib D-Bus 代理失败(具体表现为 G_IS_DBUS_PROXY 断言失败、无法向 logind 申请
inhibitor lock),属于服务与该沙箱选项的兼容性问题。通过 override
关闭这一项即可恢复正常,安全影响很小(其余沙箱选项全部保留)。