Debian 6重启时init.d脚本未执行问题排查与并发启动模式解决方案


阅读 9 次

问题现象描述

在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脚本的依赖关系处理发生了变化:

  1. X-Stop-After声明的依赖关系在并行模式下可能被忽略
  2. umountfs服务可能先于selfheal脚本执行完成
  3. 缺少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 "停止超时"
}