问题现象描述
在Debian 6系统中,一个原本在Debian 4/5上正常工作的init.d脚本出现了异常行为:
### BEGIN INIT INFO
# Provides: selfheal
# Required-Start:
# Required-Stop:
# X-Start-Before: mountall
# X-Stop-After: umountfs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: selfheal tool
# Description: Saves/restores the user partition at (re)boot
### END INIT INFO
关键异常表现
- 系统启动时脚本正常执行(runlevel 2-5)
- 系统重启时(runlevel 6)脚本未被调用
- 检查发现/etc/rc6.d/下存在正确的K10selfheal符号链接
并发启动模式的影响
Debian 6引入了并行启动机制(CONCURRENCY=makefile),这是与之前版本的主要差异点。测试发现:
# 临时解决方案(不推荐)
sed -i 's/CONCURRENCY=makefile/CONCURRENCY=none/' /etc/init.d/rc
根本原因分析
在并行启动模式下,init脚本的依赖关系处理发生了变化:
- X-Stop-After声明的依赖关系在并行模式下可能被忽略
- umountfs服务可能先于selfheal脚本执行完成
- 缺少Required-Stop声明导致系统不保证执行顺序
推荐解决方案
修改LSB头部声明,增加完整的依赖关系:
### BEGIN INIT INFO
# Provides: selfheal
# Required-Start: $local_fs $network $named $time
# Required-Stop: $local_fs $network $named
# Should-Start: $syslog
# Should-Stop: $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Self-healing filesystem tool
# Description: Automated partition recovery with checksum verification
### END INIT INFO
调试技巧
检查脚本执行日志:
# 查看启动日志
grep 'selfheal' /var/log/boot.log /var/log/syslog
# 手动测试stop操作
service selfheal stop
# 检查运行级别
runlevel
高级配置方案
对于需要精确控制执行顺序的场景,可以创建systemd服务单元:
# /etc/systemd/system/selfheal.service
[Unit]
Description=Self-healing filesystem service
Before=umountfs.service
After=local-fs.target
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStop=/etc/init.d/selfheal stop
[Install]
WantedBy=multi-user.target
兼容性注意事项
- 保留原始的init.d脚本以保证向后兼容
- 使用insserv工具验证依赖关系:
insserv -n -v /etc/init.d/selfheal
- 考虑添加pre-stop脚本确保关键操作完成
性能优化建议
对于长时间运行的初始化脚本:
# 添加超时保护
start() {
timeout 30s /usr/bin/selfheal --start || echo "启动超时"
}
stop() {
timeout 15s /usr/bin/selfheal --stop || echo "停止超时"
}