1. 为什么 OpenBMC 离不开 systemd
OpenBMC 本质上是运行在 BMC 芯片上的 Linux 系统。它不是一个单独的管理程序,而是由大量服务共同组成的系统。
这些服务包括:
- 网络服务
- D-Bus 服务
- bmcweb
- 传感器服务
- 电源控制服务
- 风扇控制服务
- 日志服务
- 固件升级服务
- 用户管理服务
- IPMI/Redfish 相关服务
这些服务之间存在启动顺序、依赖关系和运行状态管理问题。
例如:
- bmcweb 依赖 D-Bus 和后端服务
- 传感器服务依赖底层设备和配置
- 网络服务需要在远程访问前启动
- 日志服务需要尽早启动以记录异常
- 电源控制服务需要等待相关 GPIO 或状态对象可用
如果没有统一的服务管理机制,各个进程的启动、停止、重启、依赖和日志都会变得混乱。
所以systemd 是OpenBMC 中负责启动系统、管理服务、维护依赖关系和收集日志的基础组件。
2. systemd 是什么
systemd 是 Linux 系统中的系统和服务管理器。它负责在内核启动之后接管用户空间初始化流程,并根据配置启动各种系统服务。
在传统 Linux 系统中,init 程序负责启动用户空间。而在现代 Linux 发行版和 OpenBMC 中,systemd 通常作为 PID 1 运行。
PID 1 表示系统中的第一个用户态进程。内核启动完成后,会启动 systemd,由 systemd 继续拉起后续服务。
在 OpenBMC 中,systemd 主要负责:
- 启动系统服务
- 管理服务依赖
- 监听 D-Bus 激活服务
- 控制服务启停
- 自动重启异常服务
- 管理 target 启动阶段
- 记录服务日志
- 配合 watchdog 保证系统可靠性
因此,理解 OpenBMC 的启动流程,必须理解 systemd 的基本工作方式。
3. systemd 中的 Unit
systemd 使用 Unit 描述系统资源和启动对象。
常见 Unit 类型包括:
- .service 服务进程
- .socket socket 激活
- .target 启动阶段或服务集合
- .mount 挂载点
- .timer 定时任务
- .path 文件路径监听
- .device 设备对象
在 OpenBMC 中,最常见的是 .service、.target 和 .socket。
3.1 service
.service 用来描述一个服务如何启动、停止和管理。
例如 bmcweb、phosphor-logging、entity-manager、dbus-sensors 相关服务,通常都是 systemd service。
一个 service 文件通常包含:
[Unit] Description=Example Service After=xyz.openbmc_project.ObjectMapper.service [Service] ExecStart=/usr/bin/example-service Restart=always [Install] WantedBy=multi-user.target其中:
- [Unit] 描述服务基本信息和依赖关系
- [Service] 描述进程如何启动
- [Install] 描述服务被哪个 target 拉起
下面xyz.openbmc_project.EntityManager.service的实际内容:
root@xxx:~# systemctl cat xyz.openbmc_project.EntityManager.service # /lib/systemd/system/xyz.openbmc_project.EntityManager.service [Unit] Description=Entity Manager [Service] ExecStartPre=/bin/mkdir -p /var/configuration ExecStartPre=/bin/mkdir -p /tmp/overlays ExecStart=/usr/libexec/entity-manager/entity-manager Restart=always Type=dbus BusName=xyz.openbmc_project.EntityManager [Install] WantedBy=multi-user.target Alias=dbus-xyz.openbmc_project.EntityManager.service3.2 target
.target 可以理解为一组服务的集合,也可以理解为系统启动阶段。
例如:
basic.target
multi-user.target
obmc-chassis-poweron@.target
obmc-host-start@.target
在 OpenBMC 中,除了 Linux 通用 target,还有很多 obmc-* target,用于表达 BMC、机箱、电源、主机状态等管理流程。
root@xxx:~# systemctl list-units | grep obmc-.*.targetobmc-chassis-poweron@0.target loaded active active Chassis0(Power On)obmc-chassis-powerreset@0.target loaded active active Chassis0(Reset Check)obmc-host-reset-running@0.target loaded active active Host0 running after reset obmc-host-reset@0.target loaded active active Host0(Reset Check)obmc-power-on@0.target loaded active active Power0(On)obmc-power-start-pre@0.target loaded active active Power0 On(Pre)obmc-power-start@0.target loaded active active Power0 On(Starting)以obmc-chassis-poweron@0.target为例,其内容如下:
# /lib/systemd/system/obmc-chassis-poweron@.target [Unit] Description=Chassis%i (Power On) After=multi-user.target Wants=mapper-wait@-xyz-openbmc_project-state-chassis%i.service After=mapper-wait@-xyz-openbmc_project-state-chassis%i.service Conflicts=obmc-chassis-poweroff@%i.target Wants=obmc-power-start-pre@%i.target Wants=obmc-power-start@%i.target Wants=obmc-power-on@%i.target OnFailure=obmc-chassis-poweroff@%i.target OnFailureJobMode=fail3.3 socket
.socket 用于 socket 激活。
有些服务不需要系统启动时立即运行,而是在对应 socket 被访问时再启动。这样可以减少启动开销,也可以让服务按需激活。
如下:
root@xxx:~# systemctl list-units | grep .*.socketavahi-daemon.socket loaded active running Avahi mDNS/DNS-SD Stack Activation Socket bmcweb.socket loaded active running BMC Webserver socket dbus.socket loaded active running D-Bus System Message Bus Socket dropbear.socket loaded active listening dropbear.socket rpcbind.socket loaded active running RPCbind Server Activation Socket syslog.socket loaded active running Syslog Socket systemd-coredump.socket loaded active listening Process Core Dump Socket systemd-journald-audit.socket loaded active running Journal Audit Socket systemd-journald-dev-log.socket loaded active running Journal Socket(/dev/log)systemd-journald.socket loaded active running Journal Socket systemd-networkd.socket loaded active running Network Service Netlink Socket systemd-udevd-control.socket loaded active running udev Control Socket systemd-udevd-kernel.socket loaded active running udev Kernel Socket loaded active active Socket Units4. OpenBMC 的启动大致流程
OpenBMC 启动可以简单理解为以下阶段:
Boot ROM ↓ Bootloader ↓ Linux Kernel ↓ rootfs ↓ systemd ↓ 基础服务 ↓ OpenBMC 管理服务 ↓ Web / Redfish / IPMI 可用在内核完成初始化后,会启动用户空间的第一个进程,也就是 systemd。
4.1 systemd 阶段
systemd 作为 PID 1 启动后,会读取 unit 配置,按照依赖关系启动系统服务。
在 OpenBMC 中,这个阶段会逐步启动:
- D-Bus
- systemd-journald
- 网络相关服务
- ObjectMapper
- entity-manager
- 传感器服务
- 日志服务
- 电源状态服务
- bmcweb
- IPMI/Redfish 相关服务
最终系统进入可管理状态。
5. OpenBMC 中常见服务
5.1 D-Bus 服务
D-Bus 是 OpenBMC 服务协作的核心通信机制。
systemd 会启动 D-Bus daemon,并根据服务配置启动各种注册到 D-Bus 上的服务。
常见相关服务包括:
dbus.service
xyz.openbmc_project.ObjectMapper.service
# /lib/systemd/system/xyz.openbmc_project.ObjectMapper.service [Unit] Description=Phosphor DBus Service Discovery Manager [Service] Restart=always Type=dbus ExecStart=/usr/libexec/phosphor-objmgr/mapperx BusName=xyz.openbmc_project.ObjectMapper TimeoutStartSec=300 RestartSec=5 [Install] WantedBy=multi-user.target Alias=dbus-xyz.openbmc_project.ObjectMapper.serviceObjectMapper 负责帮助其他服务查找 D-Bus 对象由哪个服务提供,是 OpenBMC 中非常关键的基础服务。
5.2 bmcweb
bmcweb 是 OpenBMC 中提供 Web UI 和 Redfish API 的服务。
它对外提供 HTTPS 接口,对内通过 D-Bus 访问后端服务。
可以理解为:
浏览器 / 自动化平台 ↓ bmcweb ↓ D-Bus ↓ OpenBMC 后端服务如果 bmcweb 没有启动,Web 页面和 Redfish 接口就不可用。
5.3 entity-manager
entity-manager 负责根据平台配置和硬件信息进行设备建模。
它会读取 JSON 配置,结合 FRU 或探测结果,创建平台硬件对象。
传感器服务、库存信息、Redfish 展示等功能都可能依赖 entity-manager 提供的对象。
5.4 dbus-sensors
dbus-sensors 相关服务负责读取底层传感器数据,并发布为 D-Bus 对象。
例如:
- 温度传感器
- 风扇转速
- 电压
- 电流
- 功耗
这些数据最终会被 Web、Redfish、日志服务和风扇控制策略使用。
5.5 phosphor-logging
phosphor-logging 负责事件日志管理。
OpenBMC 中很多服务在发生异常时,会通过 D-Bus 创建日志对象。Web 和 Redfish 可以读取这些日志,用于故障分析。
5.6 网络服务
OpenBMC 通常使用 systemd-networkd 或相关网络服务管理 BMC 网络。
网络服务启动后,管理员才能通过 SSH、Web 或 Redfish 远程访问 BMC。
6. 服务依赖关系
systemd 通过依赖关系控制服务启动顺序。
常见字段包括:
After= Before= Requires= Wants= WantedBy=6.1 After
After= 表示当前服务应该在某个服务之后启动。
例如:After=xyz.openbmc_project.ObjectMapper.service
表示当前服务应该等 ObjectMapper 启动之后再启动。
6.2 Requires
Requires= 表示强依赖。
如果依赖的服务启动失败,当前服务通常也会被停止。
6.3 Wants
Wants= 表示弱依赖。
它会尝试拉起相关服务,但依赖服务失败时,不一定导致当前服务失败。
6.4 WantedBy
WantedBy= 表示当前服务被哪个 target 拉起。
例如:WantedBy=multi-user.target
表示系统进入 multi-user 阶段时会启动该服务。
7. OpenBMC 的 target 状态管理
OpenBMC 中有很多 obmc-* target,用于表达 BMC 管理流程。
常见 target 可能包括:
obmc-chassis-poweron@0.target obmc-chassis-poweroff@0.target obmc-host-start@0.target obmc-host-stop@0.target obmc-host-shutdown@0.target这些 target 不是普通 Linux 桌面系统里的概念,而是 OpenBMC 为服务器管理流程定义的状态集合。
例如主机开机流程可能涉及:
- 设置电源 GPIO
- 等待电源稳定
- 启动主机
- 更新主机状态
- 启动相关监控服务
这些动作可以拆成多个 service,并由 target 组织起来。
这样做的好处是:
- 流程清晰
- 服务可拆分
- 状态可追踪
- 失败可定位
- 可以复用 systemd 的依赖和日志能力
8. 常用 systemd 调试命令
在 OpenBMC 上调试服务时,最常用的是 systemctl 和 journalctl。
查看系统状态:systemctl status
查看某个服务状态:systemctl status bmcwebsystemctl status xyz.openbmc_project.ObjectMapper.service
查看正在运行的服务:systemctl list-units --type=service
查看所有 target:systemctl list-units --type=target
查看失败服务:systemctl --failed
启动服务:systemctl start <service>
停止服务:systemctl stop <service>
重启服务:systemctl restart <service>
查看服务日志:journalctl -u <service>
持续跟踪日志:journalctl -u <service> -f
查看本次启动日志:journalctl -b
查看某个时间之后的日志:journalctl --since "10 minutes ago"
9. 排查服务启动问题的思路
当 OpenBMC 某个功能不可用时,可以从 systemd 角度排查。
例如 Web 页面打不开,可以检查:systemctl status bmcwebjournalctl -u bmcwebsystemctl status networkip addr
如果传感器不显示,可以检查:systemctl status xyz.openbmc_project.EntityManager.servicesystemctl list-units | grep sensorjournalctl -u xyz.openbmc_project.EntityManager.servicebusctl tree xyz.openbmc_project.ObjectMapper
如果某个服务反复重启,可以看:systemctl status <service>journalctl -u <service>systemctl cat <service>
重点关注:
- 服务是否启动
- 是否找不到依赖
- ExecStart 是否执行失败
- D-Bus 名称是否注册成功
- 配置文件是否缺失
- 权限或路径是否错误
- 是否触发 watchdog 或自动重启
10. 总结
systemd 是 OpenBMC 启动和服务管理的基础组件。
OpenBMC 从 Bootloader、Kernel 到用户空间启动后,最终由 systemd 拉起各种基础服务和管理服务。D-Bus、ObjectMapper、entity-manager、dbus-sensors、phosphor-logging、bmcweb 等组件都依赖 systemd 进行启动和运行管理。
理解 systemd 的 service、target、socket、依赖关系和日志机制,有助于理解 OpenBMC 的启动流程,也能帮助开发者快速定位服务启动失败、Web 不可用、传感器不显示、日志异常和主机控制流程失败等问题。
对于 OpenBMC 调试来说,systemctl、journalctl 和 busctl 是最常用的三类工具。掌握它们,基本就能看清 OpenBMC 从服务启动到功能运行的大部分问题。