Dinit 构建、部署与使用指南

本手册以 GNU Make 为主构建方式;Make、交叉编译及用户态示例已在上述环境验证。Meson 为可选构建方式,使用前应确认当前源码树包含 meson.build。官方原始文档见 README.mdBUILDdoc/getting_started.mddoc/linux/DINIT-AS-INIT.md 与各 man 页面。


目录

  1. 引言
  2. 环境与前置条件
  3. 获取、构建与安装
  4. 快速上手:用户态服务管理
  5. 服务配置与日常使用
  6. [高级部署:作为系统 Init](#高级部署:作为系统 Init)
  7. 故障排查
  8. 附录

1. 引言

Dinit 是一个现代、轻量且健壮的服务管理器,也可以在 Linux 上作为系统初始化程序(PID 1)运行。它主要解决以下问题:

  • 按依赖关系并行启动服务;
  • 监控前台进程,并在异常退出后按策略恢复;
  • 在依赖失效时回退相关服务,依赖恢复后再重新启动;
  • 通过简洁的文本文件描述服务;
  • 同时支持系统实例和普通用户实例。

Dinit 的设计目标是简洁、可移植、易于理解,并与设备管理、日志、网络、登录等现有组件协作,而不是把所有系统功能都纳入自身。

1.1 阅读对象

本手册面向具备 Linux 基础知识的开发、系统集成和运维人员。阅读前建议了解:

  • 进程、信号、前台/后台守护进程;
  • Linux 文件系统和挂载;
  • 用户、用户组及文件权限;
  • 启动加载器、内核命令行与 initramfs 的基本作用。

1.2 使用方式选择

场景 运行身份 服务目录 风险
用户态服务管理 普通用户 ~/.config/dinit.d 低,适合学习和应用进程托管
系统服务管理 root,但非 PID 1 /etc/dinit.d
系统 Init PID 1 /etc/dinit.d 高,需准备恢复手段

2. 环境与前置条件

2.1 硬件 / 目标平台

项目 说明
目标架构 AArch64(ARM 64-bit),对应 mr536 板卡(全志 Sunxi 系列)
内核版本 工具链二进制要求 Linux ≥ 5.15(见 file 输出 for GNU/Linux 5.15.0
运行模式 可作为系统 init(PID 1),亦可作为普通用户态服务管理器

Dinit 本身是纯 C++ 用户态程序,不依赖特殊硬件外设。作为 init 使用时建议内核已启用 devtmpfscgroups v2

2.2 编译机(宿主机)软件依赖

在 WSL(Ubuntu 22.04)中已验证可用。构建前请确保已安装:

bash 复制代码
# 宿主机原生编译器(用于生成 mconfig-gen 辅助工具,交叉编译必需)
sudo apt install -y build-essential g++ make

# 文档构建(可选,仅生成 man 页面)
sudo apt install -y m4

# Meson 构建方式所需(可选)
sudo apt install -y meson ninja-build

# 可选:能力(capabilities)支持库。本手册的交叉编译默认禁用,
#       若需启用请额外安装并交叉编译 libcap。
# sudo apt install -y libcap-dev

验证宿主机工具链:

bash 复制代码
$ g++ --version      # 宿主机 g++(Ubuntu 11.4.0 实测可用)
$ make --version     # GNU Make 4.3 实测可用

2.3 目标板(交叉)工具链

本手册使用 mr536 提供的 OpenWrt GCC 交叉工具链:

bash 复制代码
# 请将下面的路径替换为你本地的项目路径
$ ls /path/to/mr536/
toolchain-sunxi-glibc-gcc-1320          # 工具链根目录

$ ls /path/to/mr536/toolchain-sunxi-glibc-gcc-1320/bin/ | grep g++
aarch64-openwrt-linux-gnu-g++           # ← 本手册使用的 C++ 交叉编译器

$ /path/to/mr536/toolchain-sunxi-glibc-gcc-1320/bin/aarch64-openwrt-linux-gnu-g++ --version
aarch64-openwrt-linux-gnu-g++.bin (OpenWrt GCC 13.2.0 r16734+1-70dacd5d5f) 13.2.0

工具链关键路径:

路径 用途
.../bin/aarch64-openwrt-linux-gnu-g++ C++ 交叉编译器
.../aarch64-openwrt-linux-gnu/sysroot/ 目标板 sysroot(glibc + 头文件)

注意(OpenWrt 工具链特性) :编译时会出现 warning: environment variable 'STAGING_DIR' not defined。该告警无害。如需消除,可设置:

bash 复制代码
export STAGING_DIR=/path/to/mr536/toolchain-sunxi-glibc-gcc-1320/aarch64-openwrt-linux-gnu

3. 获取、构建与安装

3.1 获取源码

建议使用固定版本标签或经过验证的提交,避免生产构建随主分支变化:

bash 复制代码
git clone https://github.com/davmac314/dinit.git
cd dinit
git checkout <经过验证的版本或提交>

如源码由 Windows 检出后再进入 WSL,需注意 CRLF 行尾问题。

3.2 Make 构建(主要且推荐)

Dinit 官方主构建流程依赖 GNU Make 和支持 C++11 的编译器。官方说明 GCC 4.9+ 或 Clang 约 5.0+ 可用;工程环境建议使用仍受维护的较新编译器。

在官方直接支持的平台上,可直接运行 make 采用默认配置。需要修改安装路径、编译器或功能开关时,运行 ./configure 生成 mconfig;某些源码版本也可通过 make mconfig 生成或准备配置。

原生构建(WSL)
bash 复制代码
cd /path/to/dinit
./configure --platform=Linux
make -j"$(nproc)"
# 产物:src/dinit  src/dinitctl  src/dinit-check  src/dinit-monitor

构建产物位于 src/

产物 用途
dinit 服务管理守护进程,可作为 PID 1
dinitctl 服务控制客户端
dinit-check 服务描述检查工具
dinit-monitor 服务状态监控工具
shutdown 系统关机工具,主要供 Dinit 作为 PID 1 时使用
关键 mconfig / 配置变量
变量 作用
CXX 目标平台 C++ 编译器
CXX_FOR_BUILD 构建机编译器,交叉编译时用于宿主辅助工具
CXXOPTS / CXXFLAGS C++ 编译选项,具体名称以当前版本配置文件为准
LDFLAGS 链接选项
SBINDIR 系统管理程序安装目录
MANDIR man 页面安装目录
SYSCONTROLSOCKET 系统实例默认控制 socket

3.3 Meson 构建(可选/实验性)

仅当源码树包含 meson.build 时使用:

bash 复制代码
meson setup builddir
meson compile -C builddir

# 启用单元测试等选项时,以当前源码的 meson_options.txt 为准
meson setup builddir -Dunit-tests=true
meson test -C builddir

sudo meson install -C builddir

查看当前版本支持的选项:

bash 复制代码
meson configure builddir

Meson 选项可能随版本变化。正式交付建议优先使用项目 BUILD 文档明确支持的 Make 流程。

3.4 交叉编译(mr536 工具链,AArch64)

关键点:必须区分目标编译器 CXX 与宿主编译器 CXX_FOR_BUILD。目标 sysroot 缺少可选库时,应显式关闭相关能力。

bash 复制代码
cd /path/to/dinit

TC=/path/to/mr536/toolchain-sunxi-glibc-gcc-1320
export PATH="$TC/bin:$PATH"
export STAGING_DIR="$TC/aarch64-openwrt-linux-gnu"

rm -f mconfig
./configure \
  CXX=aarch64-openwrt-linux-gnu-g++ \
  CXX_FOR_BUILD=g++ \
  --platform=Linux \
  --disable-capabilities \
  --disable-ioprio \
  --disable-oom-adj

make -j"$(nproc)"

验证产物:

bash 复制代码
file src/dinit
readelf -l src/dinit | grep interpreter

除架构外,还应确认动态链接器路径及目标板所需共享库均存在。

3.5 安装与打包

bash 复制代码
# 安装到当前系统
sudo make install

# 安装到临时根目录/目标 rootfs
make DESTDIR=/path/to/rootfs install

# Meson
sudo meson install -C builddir
DESTDIR=/path/to/rootfs meson install -C builddir

DESTDIR 只改变本次安装根目录,适合制作固件或软件包,不应误写为目标设备的运行时路径。

3.6 构建测试

bash 复制代码
make check
make check-igr

交叉产物不能直接在 x86_64 宿主机运行;应在目标板或对应仿真环境执行运行测试。


4. 快速上手:用户态服务管理

以下流程不修改系统 Init,适合首次学习和验证。

4.1 创建用户服务目录与 boot

Dinit 用户态默认从 $HOME/.config/dinit.d 读取服务描述,并自动启动名为 boot 的服务。

bash 复制代码
# 1) 准备服务目录与 boot 服务(internal 类型,不启动外部进程)
mkdir -p ~/.config/dinit.d/boot.d
cat > ~/.config/dinit.d/boot <<'EOF'
type = internal
waits-for.d: boot.d
EOF

# 2) 后台启动 dinit(-q 静默,-u 用户态实例,-p 指定控制 socket)
src/dinit -q -u -p /tmp/dinit.sock &
sleep 1

# 3) 查看服务列表(此时仅有 boot)
src/dinitctl -u -p /tmp/dinit.sock list
# 期望输出: [[+]     ] boot

4.2 添加并管理一个 process 服务

bash 复制代码
# 写一个长期运行的 process 服务(以 sleep 模拟守护进程)
cat > ~/.config/dinit.d/sleeper <<'EOF'
type = process
command = /bin/sleep 600
restart = true
EOF

DCTL="src/dinitctl -u -p /tmp/dinit.sock"
$DCTL start sleeper     # 启动并标记为 active
$DCTL list              # 看到 sleeper 及其 pid
$DCTL status sleeper    # 查看状态:State=STARTED, 含 Process ID

$DCTL stop sleeper      # 停止服务

4.3 启用默认启动

enable 会在 boot 服务的 waits-for.d 目录中创建持久依赖:

bash 复制代码
$DCTL enable sleeper
$DCTL disable sleeper

也可直接从命令行启动指定服务,但生产配置应使用 boot 和依赖目录统一管理。

4.4 验证崩溃自动重启

bash 复制代码
$DCTL start sleeper
OLD_PID=$($DCTL status sleeper | awk '/Process ID/{print $3}')
kill "$OLD_PID"
sleep 1
$DCTL status sleeper

若新 PID 与 OLD_PID 不同,说明服务被重新拉起。测试结束:

bash 复制代码
$DCTL stop sleeper
$DCTL shutdown          # 关闭用户态 dinit 实例

实测输出(WSL 验证通过):

复制代码
[2] list
[[+]     ] boot
[3] start sleeper -> Service 'sleeper' started.
[[+]     ] boot
[[+]     ] sleeper (pid: 28550)
[4] status sleeper
    State: STARTED
    Activation: explicitly started
    Process ID: 28550
[5] stop sleeper -> Service 'sleeper' stopped.
[6] shutdown -> Shutting down dinit... / Connection closed.

5. 服务配置与日常使用

5.1 构建与配置补充参考

Dinit 使用 shell 脚本 configure + Makefile 的轻量构建系统(非 autotools/cmake):

复制代码
configure ──► mconfig            # 生成顶层构建配置(编译器/路径/特性开关)
Makefile ──► build/  + src/      # build/ 生成 mconfig-gen 工具与 mconfig.h
                                 # src/   编译各 .cc → dinit / dinitctl / ...

构建目标产物(src/ 下):

产物 说明
dinit 核心守护进程(可作 init)
dinitctl 服务控制客户端(start/stop/list/status...)
dinit-check 服务描述文件语法/依赖检查器
dinit-monitor 服务状态变更监听工具
shutdown 关机/重启工具(仅 Linux,随 dinit 一并安装到 sbin,并创建 halt/reboot/poweroff/soft-reboot 软链)
5.1.1 配置选项(./configure

常用选项(完整列表见 ./configure --help):

选项 默认(Linux) 说明
--prefix=PREFIX /usr 安装主前缀
--bindir / --sbindir / --mandir PREFIX/bin / PREFIX/sbin / PREFIX/share/man 各类文件目录
--syscontrolsocket=PATH /run/dinitctl 系统控制 socket 路径
--enable/disable-shutdown Linux 下 enable 是否构建 shutdown 系列工具
--enable/disable-cgroups enable cgroups 支持
--enable/disable-capabilities auto(有 libcap 则启用) Linux capabilities 支持(需 libcap)
--enable/disable-ioprio auto I/O 优先级(需 linux/ioprio.h
--enable/disable-oom-adj enable OOM score 调整
--enable/disable-strip enable 安装时 strip 调试信息

构建变量(可作 VAR=value 参数传入):

  • CXX:C++ 编译器
  • CXX_FOR_BUILD宿主机 编译器(交叉编译时必需,用于编译 mconfig-gen 等辅助工具)
  • CXXFLAGS / CXXFLAGS_EXTRA:编译选项
  • LDFLAGS / LDFLAGS_EXTRA:链接选项
  • --platform=PLATFORM:手动指定平台(交叉编译时建议显式给出,如 Linux
5.1.2 交叉编译参考(mr536 工具链,AArch64)

关键点:交叉编译必须同时指定 目标 CXX宿主机 CXX_FOR_BUILD(后者用于编译运行于构建机的辅助工具)。目标板通常无 libcap/ioprio/oom 相关头文件,建议在交叉编译时禁用这些可选特性。

bash 复制代码
cd /path/to/dinit

# 配置(推荐写成脚本以免 PATH 引号问题)
cat > /tmp/build-mr536.sh <<'SH'
#!/bin/bash
set -e
cd /path/to/dinit
TC=/path/to/mr536/toolchain-sunxi-glibc-gcc-1320
export PATH="$TC/bin:$PATH"                       # 让 configure 能找到交叉 g++
export STAGING_DIR="$TC/aarch64-openwrt-linux-gnu" # 消除 OpenWrt 的 STAGING_DIR 告警(可选)

rm -f mconfig
./configure \
    CXX=aarch64-openwrt-linux-gnu-g++ \
    CXX_FOR_BUILD=g++ \
    --platform=Linux \
    --disable-capabilities \
    --disable-ioprio \
    --disable-oom-adj

make -j"$(nproc)"
SH
bash /tmp/build-mr536.sh

验证产物架构:

bash 复制代码
$ file src/dinit
src/dinit: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV),
  dynamically linked, interpreter /lib/ld-linux-aarch64.so.1,
  for GNU/Linux 5.15.0, not stripped

构建说明

  • 交叉编译时 configure 会自动禁用 -fno-rtti(规避部分平台编译器与异常处理的 bug),属正常行为。
  • -flto-fsanitize(仅测试用)等会在 configure 阶段自动探测是否可用。
  • 生成的 mconfig 为顶层配置,make 时会据此生成 build/includes/mconfig.h
5.1.3 安装参考
bash 复制代码
# 安装到目标板根文件系统(DESTDIR 方式,常用于嵌入式打包)
make DESTDIR=/path/to/rootfs install
# 产物落点:
#   $DESTDIR/usr/bin/{dinit,dinitctl,dinit-check,dinit-monitor}
#   $DESTDIR/sbin/{shutdown,halt,reboot,soft-reboot,poweroff}
#   $DESTDIR/usr/share/man/man{5,8}/...
5.1.4 测试参考(需原生环境)
bash 复制代码
make check        # 单元测试(src/tests)
make check-igr    # 集成测试(src/igr-tests)

交叉编译产物的测试需在目标板上执行;宿主机上 make check 使用的是原生编译产物。


5.2 服务配置

5.2.1 服务描述文件

Dinit 通过服务描述文件发现服务。每个文件即一个服务,文件名=服务名。

角色 默认搜索目录
系统实例(root) /etc/dinit.d,其次 /usr/local/lib/dinit.d/lib/dinit.d
用户实例 $HOME/.config/dinit.d

服务按需懒加载(首次 start/被依赖时才读取描述文件)。

服务类型(type
类型 说明
process 前台常驻进程,dinit 直接持有并监控其 pid(首选
bgprocess 会自行 fork 到后台(如传统 daemon),通过 pid-file 追踪
scripted 由脚本启动/停止(执行到完成即视为 started)
internal 无外部进程,常用于分组/检查点(如 bootloginready
triggered 需外部触发事件才能启动

重要原则 :把守护进程跑成前台模式 注册为 process,dinit 才能监控它。例如 sshd 用 /usr/sbin/sshd -D、smbd 用 -F(foreground)。

常用配置项
ini 复制代码
type = process                 # 服务类型
command = /usr/sbin/sshd -D    # 启动命令(前台运行!)
stop-command = ...             # 停止命令(可选)
run-as = nobody                # 以指定用户运行
restart = true                 # 崩溃后自动重启
logfile = /var/log/foo.log     # 日志文件(该路径必须在该服务启动前可写!)
pid-file = /run/foo.pid        # bgprocess 的 pid 文件
# 依赖关系(见 5.2.2)
depends-on:  <svc>             # 硬依赖:被依赖服务必须先启动成功
depends-ms:  <svc>             # 机器启动依赖:类似 depends-on 但不强制运行时同步
waits-for:   <svc>             # 等待:等它启动完再启动本服务,但不要求它成功
after:       <svc>             # 仅排序,无依赖语义(尽量少用)
# 选项(options:)
options: starts-log            # 此服务就绪后开始把 dinit 缓冲日志落盘

完整选项见 man 页 dinit-service(5)

5.2.2 依赖关系(核心概念)

Dinit 的精髓在于依赖。启动一个服务会 拉起其依赖;停止一个无人依赖的服务会级联停止其依赖。

复制代码
boot ──depends-on──► loginready ──depends-on──► syslogd
                                            └──► dbusd
       └──waits-for.d: boot.d/ ──► (各开机自启服务)

依赖关键字选择建议:

  • 关键依赖用 depends-on::被依赖失败时本服务也不启动,能让 boot 失败被正确感知 → 触发恢复流程。
  • waits-for: 仅做时序等待,阻断启动;用于非关键前置。
  • 尽量避免 after:/before:(无依赖语义、不会级联停止)。
5.2.3 默认启动(bootwaits-for.d

boot 是 dinit 默认拉起的服务。典型写法:

ini 复制代码
# /etc/dinit.d/boot
type = internal
waits-for.d: boot.d        # boot.d/ 中每个软链指向一个开机自启服务

通过 dinitctl enable/disable <svc> 自动在 boot.d/ 创建/删除软链,实现开机自启管理(等价于 systemd 的 enable)。

5.2.4 process 示例:sshd
ini 复制代码
# /etc/dinit.d/sshd
type = process
command = /usr/sbin/sshd -D
restart = true
waits-for: syslogd
depends-on: loginready

更多系统级服务模板见 doc/linux/services/(含 bootudevdfilesystemsrcbootsyslogdttyNrecoverysingle 等)。

5.2.5 scripted 示例:一次性初始化
ini 复制代码
# /etc/dinit.d/app-prepare
type = scripted
command = /usr/local/libexec/app-prepare start
stop-command = /usr/local/libexec/app-prepare stop
depends-on: root-rw
start-timeout = 30
stop-timeout = 10

scripted 服务的启动命令成功退出后,服务才进入 started 状态。脚本必须正确返回退出码,并保证重复执行安全。

5.2.6 配置校验与热加载

部署前务必用 dinit-check 检查服务描述语法与依赖错误:

bash 复制代码
dinit-check /etc/dinit.d/sshd            # 检查单个文件
dinit-check -d /etc/dinit.d              # 检查整个目录
dinitctl reload sshd                     # 重新读取简单配置改动
dinitctl restart sshd                    # 需要时重启以使配置生效

6. 高级部署:作为系统 Init

!WARNING

Dinit 作为 PID 1 时,服务文件、挂载或登录配置错误可能导致设备无法启动或无法登录。必须先备份 rootfs、保留串口控制台或救援系统,并在测试环境验证。

6.1 前提准备

  • 可修改内核命令行的引导加载程序,例如 GRUB 或 U-Boot;
  • 可用的 initramfs/initrd 或等效早期启动逻辑;
  • initramfs 能挂载 /proc/sys/dev/run,并最终执行根文件系统中的 /sbin/init
  • 设备节点管理器(如 eudev)、getty/login、shell、日志服务及网络工具;
  • 串口、救援分区、可回滚 A/B 分区或其他恢复通道。

6.2 最小系统服务集合

实际名称可调整,但通常至少需要:

服务 类型建议 作用
boot internal 系统默认启动目标
early-filesystems scripted 准备 /proc/sys/dev/run
root-rw / filesystems scripted fsck、根分区读写及其他挂载
udevd process 设备事件与节点管理
syslogd process 系统日志
network scriptedprocess 网络初始化
loginready internal 登录服务前置检查点
tty1 / serial-getty process 本地或串口登录
recovery scriptedprocess 启动失败后的恢复入口

getty 示例:

ini 复制代码
# /etc/dinit.d/tty1
type = process
command = /sbin/agetty --noclear tty1 linux
restart = true
depends-on: loginready
options: runs-on-console

串口设备名、波特率和终端类型必须按目标板修改。

6.3 部署步骤

部署步骤:

  1. 交叉编译并安装到 rootfs(见第 3 章)。
  2. 准备服务描述 :将 doc/linux/services/ 模板按板子实际情况修改后放入 $ROOTFS/etc/dinit.d/
  3. initramfs 预挂载 (推荐由 initramfs 完成):/proc/sys/dev(devtmpfs)、/run(tmpfs)。其中 /run 可写是 dinit 能立即创建控制 socket 的前提。
  4. 离线检查配置 :对目标 rootfs 中的服务目录执行 dinit-check
  5. 低风险测试 :不替换原 /sbin/init,通过一次性内核参数 init=/sbin/dinit 启动。
  6. 验收:确认文件系统、设备节点、网络、日志、登录、关机和重启均正常。
  7. 正式启用 :验证通过后,再让 /sbin/init 指向已安装的 Dinit。
bash 复制代码
ln -sfn /usr/bin/dinit "$ROOTFS/sbin/init"

执行前必须确认实际安装路径;某些配置会把 dinit 安装到 /sbin/dinit

启动流程(由服务实现):

复制代码
挂载早期虚拟文件系统 → 启动 udevd → 设硬件时钟 → fsck 根文件系统
→ 根文件系统重挂为 rw → 清理 /tmp、/var/run,配 lo,设主机名
→ 启动 syslogd → 启动其他 daemon(网络/ssh...)→ loginready → getty 登录

6.4 测试与回滚清单

  • 启动前记录原始 /sbin/init 指向;
  • 不删除原 Init 二进制及其配置;
  • 保存一条可从引导菜单恢复原 init= 参数的启动项;
  • 验证 boot 失败时能进入 recovery shell;
  • 验证串口或本地 getty 可登录;
  • 验证 dinitctl shutdown、重启及断电流程;
  • 验证看门狗、挂载、网络和核心业务服务;
  • 正式切换后首次启动安排现场或远程恢复人员值守。

7. 故障排查

7.1 运行时控制速查(dinitctl

bash 复制代码
dinitctl list                       # 列出所有已加载服务及状态
dinitctl status <svc>               # 单个服务详情(含 pid)
dinitctl start   <svc>              # 启动并标记 active
dinitctl stop    <svc>              # 停止(会停止其独占的依赖)
dinitctl release <svc>              # 取消 active 标记,无依赖则停止(更"软"的 stop)
dinitctl enable  <svc>              # 开机自启(在 boot.d 建软链)
dinitctl disable <svc>              # 取消开机自启
dinitctl start --pin <svc>          # 固定为启动态(禁止被 stop/级联停止)
dinitctl unpin  <svc>               # 解除固定
dinitctl shutdown                   # 关闭 dinit(停止所有服务)

状态图例:

显示 含义
[[+] ] 已启动 + 显式 active
[{+} ] 已启动,但仅因被依赖而运行(非显式 active)
[ {-}] 已停止
<< / >> 正在启动 / 正在停止

用户态/系统实例选择:root 默认连系统实例;普通用户默认连用户实例。-s 强制系统实例、-u 强制用户实例,-p PATH 指定控制 socket。

7.2 常见问题

A. ./configurebad interpreter: /bin/sh^M

源码含 Windows CRLF 行尾。执行 dos2unix configure configs/mconfig.Linux.sh Makefile src/Makefile build/Makefile build/tools/Makefile

B. CXX is not a working C++ compiler / command not found

交叉编译时未把工具链加入 PATH,或未用脚本统一 export PATH(命令行直接传含空格/括号的 PATH 易出错)。确保 export PATH=/opt/toolchain/mr536/toolchain-sunxi-glibc-gcc-1320/bin:$PATH同时 指定 CXX_FOR_BUILD=g++

C. STAGING_DIR not defined 告警

OpenWrt 工具链 wrapper 的无害告警。消除:export STAGING_DIR=/opt/toolchain/mr536/toolchain-sunxi-glibc-gcc-1320/aarch64-openwrt-linux-gnu

D. 交叉编译链接报 cannot find -lcap / 找不到 capabilities 头文件

目标 sysroot 缺 libcap。若目标板不需要 capabilities,构建时加 --disable-capabilities(本手册默认即如此)。

E. 服务启动失败:logfile 不可写

logfile 指定的目录在该服务启动时刻必须可写。根文件系统在 rootrw(重挂 rw)之前是只读的 → 早期服务应把日志放 /run,或用 log-type = buffered 缓存在内存。

F. 服务偶发启动失败 / 时序问题

通常是漏声明依赖 (并行启动下偶发竞态)。为关键服务补 depends-on:(文件系统可写、伪文件系统挂载、系统时间、syslog)。不要依赖启动顺序"碰运气"。

G. 控制台服务死锁/卡住

runs-on-console 同时只能有一个服务占用控制台。仅需显示输出用 shares-console;确需独占输入再用 runs-on-console

H. 调试启动问题
  • 用 shell 脚本代替 /sbin/init,在其中 exec dinit 并传任意参数。
  • 临时在某 tty 放一个 command = /sbin/agetty tty6 linux-c -n -l /bin/bash、去掉依赖、设 term-signal = nonestop-timeout = 0,保留一个常驻调试 shell。
  • dinit-check 预检服务描述。
I. WSL 下运行报 socket/权限问题

WSL 中建议用户态测试用 -u -p /tmp/dinit.sock 显式指定 socket 路径,避免与系统 socket 冲突。

7.3 日志与监控

  • 服务输出默认可由 logfile 落盘;未指定时早期可 log-type = buffered 缓存。
  • dinit-monitor <svc> -- <cmd> 可在服务状态变化时执行命令(接告警/通知)。
  • 系统启动日志由 syslogd 承接(需 starts-log 选项触发 dinit 把缓冲日志刷出)。

8. 附录

8.1 dinitctl 命令速查

命令 作用
start <svc> 启动并显式激活服务
stop <svc> 停止并取消显式激活
restart <svc> 重启服务
wake <svc> 启动但不显式激活
release <svc> 取消显式激活,无活动依赖者时自动停止
status <svc> 查看服务状态、PID 和失败原因
list 列出已加载服务
enable <svc> 持久加入默认启动依赖
disable <svc> 删除对应的默认启动依赖
reload <svc> 重新加载允许在线变更的描述项
catlog <svc> 查看 buffer 类型日志
signal <sig> <svc> 向服务进程发送信号
shutdown 停止全部服务;系统实例会进入系统关机流程

disable 只移除指定的持久 waits-for 依赖;若其他服务依赖该服务,它仍可能被启动。

8.2 关键路径速查表

用途 路径 / 命令
交叉编译器 /opt/toolchain/mr536/toolchain-sunxi-glibc-gcc-1320/bin/aarch64-openwrt-linux-gnu-g++
sysroot /opt/toolchain/mr536/toolchain-sunxi-glibc-gcc-1320/aarch64-openwrt-linux-gnu/sysroot
系统服务目录 /etc/dinit.d
用户服务目录 ~/.config/dinit.d
系统控制 socket /run/dinitctl(可经 --syscontrolsocket 改)
构建配置 顶层 mconfig(由 ./configure 生成)
服务模板参考 doc/linux/services/
官方文档 README.mddoc/getting_started.mddoc/linux/DINIT-AS-INIT.md、man 页

8.3 官方参考


本手册中 Make 交叉编译与用户态快速启动流程已在 WSL Ubuntu 22.04 + mr536 工具链环境下实测;系统 Init 切换必须在具体目标板上另行完成恢复演练与验收。

相关推荐
别动我齐刘海6 小时前
机器人运动控制学习2——基础进阶
c++·人工智能·神经网络·学习·目标检测·机器学习·机器人
傻啦嘿哟7 小时前
英雄联盟皮肤爬虫:爬取全皮肤价格与特效,做比价工具
java·c++·爬虫
码匠许师傅8 小时前
【C++ 面试真题】24. 聊聊 C++ 的时间日期处理
java·c++·面试
闻道且行之8 小时前
图片处理助手|泊松融合原理 + C++ 工程实现,seamlessClone 三模式一次讲透
数据库·c++·人工智能·opencv
莫浅子9 小时前
day01-USB架构与枚举
c++·单片机·嵌入式驱动
小欣加油9 小时前
leetcode3069 将元素分配到两个数组中I
数据结构·c++·算法·leetcode·职场和发展
不会代码的小猴10 小时前
7. JSON
开发语言·c++·笔记·qt·算法·json
沫璃染墨10 小时前
《Qt从零入门系列(六):信号与槽进阶——从多种连接方式到Lambda表达式》
开发语言·c++·qt·代码规范·设计规范·qt5
小小龙学IT11 小时前
ZeroMQ(libzmq)开源消息库深度解析:brokerless 时代的轻量消息内核
c++·开源
Benny_Tang12 小时前
题解:P10230 [COCI 2023/2024 #4] Lepeze
c++·算法